Get a free advice now!

    Pick the topic

    Developer OutsourcingWeb developingApp developingDigital MarketingeCommerce systemseEntertainment systems

    Thank you for your message. It has been sent.

    Tags

    Iframe – change window size (cross domain)

    Iframe – change window size (cross domain)

    CHALLENGE: change iframe size from the inside

    SOLUTION: use browser window.postMessage() Web API

    We would like to embed our React App inside iframe on a third-party domain. How to add the ability to dynamically change window size from inside the iframe? Let’s find out.

    Websites are protected by CORS policy, which forbids iframes from making changes in the parent site DOM. This security policy blocks malicious actions from third-party embeds.

    postMessage

    By default, scripts can modify DOM of the page only if they share the same host and protocol (same origin policy). The window.postMessage() method enables cross-origin communication between a page and an iframe embedded within it. It allows to dispatch MessageEvent from one window and to receive it in another.

    Iframe – changing window size

    We need to take 2 steps to have the ability to change iframe size (width and height) and trigger it from iframe code:

    • add iframe code to the parent page and window.addEventListener
    • use postMessage inside iframe to trigger size changes

    Iframe embed

    We’re going to paste our iframe embed code on the parent website. There is parent div “iframe-parent” that controls the width and height, and iframe displays our React App content. The last part is window.addEventListener that is waiting to receive messages from iframe. When a message is received, inline styles are applied to the div.

    <!-- public/parent.html  -->
    <html>
    <head></head>
    <body style="background:#ccc; border:4px solid #999; padding:10px; margin:0;">
    <h1>This is parent page</h1>
    <div id="iframe-parent"
         style="border: 0px;
         background-color: #282c34;
         pointer-events: none;
         z-index: 2147483639;
         position: fixed;
         bottom: 0px;
         width: 300px;
         height: 400px;
         overflow: hidden;
         opacity: 1;
         max-width: 100%;
         right: 0px;
         max-height: 100%;">
        <iframe src="http://localhost:3001" id="iframe-source"
                style="pointer-events: all;
                background: none;
                border: 0px;
                float: none;
                position: absolute;
                inset: 0px;
                width: 100%;
                height: 100%;
                margin: 0px;
                padding: 0px;
                min-height: 0px;">
        </iframe>
    </div>
    <script>
        // communication
        const iframeParent = document.getElementById("iframe-parent");
        window.addEventListener('message', function (e) {
            let message = e.data;
            if (!iframeParent) {
                return;
            }
            iframeParent.style.height = message.height;
            iframeParent.style.width = message.width;
            iframeParent.style.background = message.background;
        }, false);
    </script>
    </body>
    </html>

    Change iframe parent size

    Iframe uses React to showcase an example of using window.parent.postMessage. But it’s just javascript, it can be used without React. It is enough to use plain javascript to establish a connection with iframe. On button click, we’re sending a message to the parent page to adjust the styles of div with ID #iframe-parent. Active class is just for better presentation (highlighting the recently clicked button).

    // src/App.jsx
    import React, {useState} from 'react';
    import './App.css';
    function App() {
      const [active, setActive] = useState('button0');
      const changeIframeParentSize = (width = '300px', height = '300px', background = '#282c34') =>{
        let message = { height: height, width: width, background: background };
        window.parent.postMessage(message, "*");
      }
      return (
        <div className="App">
          <header className="App-header">
            <div className={'App-body'}>
              <h2>Change window size from iframe</h2>
              <button id={'button0'}
                      key={'button0'}
                      className={active === 'button0' ? "active" : undefined}
                      onClick={(event)=> { setActive(event.target.id); changeIframeParentSize('300px','400px')}}>300px x 400px</button>
              <button id={'button1'}
                      key={'button1'}
                      className={active === 'button1' ? "active" : undefined}
                      onClick={(event)=> { setActive(event.target.id); changeIframeParentSize('800px','800px')}}>800px x 800px</button>
              <button id={'button2'}
                      key={'button2'}
                      className={active === 'button2' ? "active" : undefined}
                      onClick={(event)=> { setActive(event.target.id); changeIframeParentSize('400px','400px', 'pink')}}>400px x 400px and pink</button>
              <button id={'button3'}
                      key={'button3'}
                      className={active === 'button3' ? "active" : undefined}
                      onClick={(event)=> { setActive(event.target.id); changeIframeParentSize('600px','600px')}}>600px x 600px</button>
              <button id={'button4'}
                      key={'button4'}
                      className={active === 'button4' ? "active" : undefined}
                      onClick={(event)=> { setActive(event.target.id); changeIframeParentSize('300px','500px', 'red')}}>300px x 500px and red</button>
            </div>
          </header>
        </div>
      );
    }
    export default App;

    and styles needed for the Demo example:

    .App {
      text-align: center;
      background-color: transparent;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      color:#fff;
      padding:20px;
    }
    .App-body button {
      cursor:pointer;
      margin:10px;
      border:0;
      padding:5px 10px;
      background:#fff;
      color:#282c34;
    }
    .App-body button.active {
      background:darkslategrey;
      color:#fff;
    }

    Changing styles from iframe

    Changing width and height of div is only one option. You can also change any other styles from iframe. It’s just a matter of passing an additional parameter to the changeIframeParentSize function and adding an extra line in parent.html :

    <script>
    // communication
    ..
    iframeParent.style.background = message.background;
    </script>

    Cross domain

    In our example, we’re using the same domain: http://localhost:3001/parent.html and http://localhost:3001 for iframe source. So, technically, we don’t have proof that this will work cross-origin (having a parent website and iframe using different domains).

    If we have the React application, we can upload our code to Netlify really fast and test it cross domain. For Netlify deployment, we need to execute the following in the console:

    // One time:
    npm install netlify-cli -g
    // To deploy the code:
    npm run build
    netlify deploy
    build (Publish directory)
    netlify deploy --prod

    Now, we can visit the /parent.html site hosted on Netlify, and iframe will be still pointing to the localhost url. I have good news, it is still working! PostMessage API provides an easy way to enable communication with iframe having the parent website hosted on a different domain.

    Animation of a browser window and switching between website window sizes

    That’s it for today’s tutorial. Make sure to follow us for other useful guidelines and don’t forget to sign up for our newsletter.

    Comments
    0 response

    Add comment

    Your email address will not be published. Required fields are marked *

    Popular news

    A game changer for WooCommerce users
    • Our Highlights

    A game changer for WooCommerce users

    March 24, 2023 by createIT
    The differences between a web app and a mobile app
    • Services
    • Technology
    • Trends

    The differences between a web app and a mobile app

    March 7, 2023 by createIT
    Webrooming and showrooming
    • Trends

    Webrooming and showrooming

    February 14, 2023 by createIT
    PHPStorm – fix long load time of a directory window
    • Dev Tips and Tricks

    PHPStorm – fix long load time of a directory window

    January 20, 2023 by createIT
    reCAPTCHA v3 – WordPress implementation
    • Dev Tips and Tricks

    reCAPTCHA v3 – WordPress implementation

    January 20, 2023 by createIT
    How to compare GIT and server files
    • Dev Tips and Tricks

    How to compare GIT and server files

    January 19, 2023 by createIT
    How to trigger a click event inside iframe?
    • Dev Tips and Tricks

    How to trigger a click event inside iframe?

    January 19, 2023 by createIT
    FOOEvents – generate a custom CSV report
    • Dev Tips and Tricks

    FOOEvents – generate a custom CSV report

    January 19, 2023 by createIT
    Headless chrome – testing webgl using playwright
    • Dev Tips and Tricks

    Headless chrome – testing webgl using playwright

    January 18, 2023 by createIT
    Preview big SQL files with PilotEdit
    • Dev Tips and Tricks

    Preview big SQL files with PilotEdit

    January 18, 2023 by createIT

    Support – Tips and Tricks
    All tips in one place, and the database keeps growing. Stay up to date and optimize your work!

    Contact us