-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Motivation
Right now if the website connected to the SDK is run inside of an iframe (other than WS), the redirect feature and Web Spotlight features (enable/disable editable elements, in-context editor, etc.) won't work. This happens because the SDK assumes that the iframe, it is being run inside of, is a Web Spotlight preview iframe and tries sending messages to this iframe which are left unprocessed. Currently, there is no way to override this behavior.
Proposed solution
First of all, we need to decide whether we want to somehow fix this issue or not. There are several possible solutions that can be used to solve it:
- We can add a boolean flag to the SDK configuration object that will allow users to disable the iframe communication. This way when someone wants to wrap a website connected to the SDK with an iframe, they can disable the iframe communication feature and smart links will always open Kontent in a new tab instead of sending iframe messages. The main disadvantage of this method is that without the iframe communication smart links will open Kontent in a new tab even in Web Spotlight because Web Spotlight requires iframe communication to work properly.
- We can add some public helpers to SDK that will help users with this problem (more information about this can be found in the Workaround section of this issue).
Workaround
If you plan on using the website (connected to the SDK) inside of an iframe, you can use this workaround to make everything work properly with Web Spotlight.
The first thing you need to do is listen to all message
events on your host page window object.
window.addEventListener('message', handleMessage);
Then whenever you receive a new message, you need to check whether it is a message related to SDK. If it is related to the SDK, you need to check if you are currently inside an iframe and if you aren't, you just generate a smart link (using buildKontentLink
helper from @kentico/kontent-smart-link
) and open it in a new tab. If you are inside an iframe, you need to check the direction of the received message (upwards from inner iframe/downwards from parent window) by comparing the source of this event to the iframe content window. Finally, you need to resend the whole event to the parent window or inner iframe according to the event direction.
import { buildKontentLink } from '@kentico/kontent-smart-link';
function handleMessage(event) {
const eventTypeRegex = /^kontent-smart-link:/;
// check if this message is not related to the SDK
if (!event.data || !event.data.type || !eventTypeRegex.test(event.data.type)) {
return;
}
const isInsideIFrame = window.self !== window.parent;
const message = event.data;
if (isInsideIFrame) {
// The iframe variable has a reference to the iframe element.
// You don't have to use document.querySelector here, for example,
// in React you can use `useRef` hook to save the reference and then
// use it here, in Vue you can use `$refs`, etc.
const iframe = document.querySelector('#your-iframe-id');
const isMessageGoingUpwards = event.source === iframe.contentWindow;
if (isMessageGoingUpwards) {
// resend this message to the parent window
window.parent.postMessage(message, '*');
} else {
// resend this message to the iframe
iframe.contentWindow.postMessage(message, '*');
}
} else if (message.type === 'kontent-smart-link:element:clicked') {
const link = buildKontentLink(event.data.data);
window.open(link, '_blank');
}
}
Additional context
Add any other context, screenshots, or reference links about the feature request here.