Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Website with SDK cannot be used inside of an iframe (other than WS) #16

Closed
vladbulyukhin opened this issue Oct 15, 2020 · 1 comment
Closed
Assignees

Comments

@vladbulyukhin
Copy link

vladbulyukhin commented Oct 15, 2020

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.

@vladbulyukhin vladbulyukhin changed the title Make it possible to disable iframe communication Website with SDK cannot be used inside of an iframe (other than WS) Oct 15, 2020
@vladbulyukhin vladbulyukhin self-assigned this Oct 22, 2020
@vladbulyukhin
Copy link
Author

Since we changed the behavior of the SDK inside iframes, this issue can be closed.

Starting from version 2.0.0, when the SDK is loaded inside an iframe, which is not a Web Spotlight preview iframe, it works the same as outside the iframe, i.e. only some functions are available, and user actions will redirect users to Kontent in a new browser tab. You can read more about it in the README file.

The workaround that allows multiple levels of nested iframes inside Web Spotlight has been added to the TROUBLESHOOTING file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant