Brian Krausz

I build internet things

TIL iframe history is shared with the parent page

September 3, 2020

Apparently when using browser history inside of an iframe (e.g. via history.pushState), the browser’s global navigation buttons affect it, basically blending the page history with the iframe history. This is incorrect when you want your iframe to act as a separate application (for example, if it’s injected via an extension).

If someone navigates to our app directly, we want it use browser URLs so links can be shared, back buttons work, etc. But when we’re inside of an iframe we don’t want to mess with global navigation. This can be accomplished using React Router:

// App.tsx
import { createBrowserHistory, createMemoryHistory } from 'history';
import { Router } from 'react-router-dom';

const isInIframe = window.self !== window.parent;
const history = isInIframe ? createMemoryHistory() : createBrowserHistory();

export default function App() {
  return <Router history={history}>
    {/* Normal Router contents, e.g. <Switch> */}
  </Router>;
}

This way when running as a separate window proper URLs are supported, but you don’t inadvertently take over browser navigation inside an iframe.

Share This Post