Documentation

Iframe Integration: Handling message Events

When embedding the player within an iframe, please exercise caution if you are globally listening for window.postMessage events in the parent window.

The player communicates with the parent window by sending specific string messages to signal state changes or request actions. If your application listens for all incoming messages without filtering, this may lead to conflicts, parsing errors (e.g., if you expect JSON but receive a simple string), or unexpected behavior.

Potential Issue

A common integration scenario involves the parent application setting up a global listener that assumes all messages adhere to a specific format (e.g., resizing coordinates).

Consider the following existing code in a parent application:

window.addEventListener("message", (event) => {
    if (!event.data || typeof event.data !== 'string') {
        return;
    }

    var size = event.data.split(",");
    var myframe = document.getElementById("myiframe");
    myframe.style.width = parseFloat(size[0]);
    myframe.style.height = parseFloat(size[1]);
});

For example, when the lesson page changes, the player attempts to execute a scroll. However, when embedded in an iframe, the player cannot scroll the parent window directly. To solve this, the player sends alaso a specific message: SCROLL_VIEW_TOP via window.parent.postMessage.

If the code above receives SCROLL_VIEW_TOP, the split operation fails to produce the expected dimensions, potentially causing errors in the resizing logic.

To ensure the page scrolls correctly when the player is inside an iframe, you can add a handler in the parent/top window that listens for this specific string.

Below is a corrected example of how to implement this safely:

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event) {
    if (!event.data || typeof event.data !== 'string') {
        return;
    }

    if (event.data.indexOf("SCROLL_VIEW_TOP") === 0) {
        window.scrollTo(0, 0);
    } else if (event.data.indexOf("RESIZE_VIEW") === 0) {
        const sizeData = data.substring('RESIZE_VIEW'.length)           
        const size = sizeData .split(","); 
        // resize logic goes here
    }
}

Proper implementation of receiveMessage prevents your application from crashing due to unexpected message formats and ensures that intended interface actions (like scrolling to the top of the lesson) occur seamlessly.