Embedding iframes - best practices

Published on

If you have a site and you want your customers to embed a widget.

E.g. you have a calculator, and you want your customers to emebed that calculator on their site. Maybe it is using React. You host the calculator on your site. Or maybe you have your own mapping system and you want your customers to include a map widget in an iframe on their site.

Filesize / performance

  • Keep your file size small. Third party code can really slow down a site, and people won't be keep to embed your widget if it slows down their page.
  • Avoid adding third party scripts in your iframe. You might want some basic stats, but make sure your widget doesn't include things like live chat agents etc. Be sure to check this on production in an incognito window - its easy to miss things locally, as you may have clicked "never show this again" for cookie notices etc.

Facades

You might think you need to load a full React app that is interactive in your widget... but maybe you can get away with a simple facade.

This can be a static image (prerendered) that looks similar, and once the user interacts with your widget then it loads the real content (DOM. JS, etc). This means users get to see the content quicker, but it will slow down their interaction speed. (This is known as 'click to load').

You can also load the real app/content on mouse movement on the iframe.

Avoid layout shifts to increase performance

Every time positions/sizes of elements change, there is a layout shift. Avoid these by setting width/height on your embed (and avoid changing it if possible).

This is also something to think about if you are embedding another service's iframe. Try to avoid letting the 3rd party script from adjusting the dimensions (you could force it with iframe { width: 500px !important}. But be careful, it might break things.

Lazy loading

  • If loading your content is done via JS, see if you can run it with <script async> (does not block the page while loading the JS, and executes as soon as its loaded) or maybe <script defer> to not block while loading, and only execute after the DOM has been parsed.
  • Lazy load content
    • Lazy load any content within your iframe embed
    • But you can lazy load the iframe in some modern browsers. <iframe src="https://yoursite.com/embed" loading="lazy"></iframe>
    • There are a couple of options to loading - loading="lazy which will wait to load the iframe content until the user scrolls the viewport near the iframe. and loading="eager" to load it as soon as possible (default behaviour). There is also loading="auto" to let the browser decide.
    • Not all browsers support the lazy attribute. You can also also use JS libraries such as lazysites to manage lazy loading your iframe content.
  • You can also do it manually - start without a src property, then once the document is loaded then set the src property.

Same domain iframe resizing

Normally an iframe (child) cannot easily tell the parent (which has the <iframe width="500" height="500"> code) how big of dimensions it actually needs.

But with some JS you can get around that...

If you are iframing some content from the same domain, the parent can get access to the true height of the child iframe, and can adjust the height.

This can be done via document.querySelector('iframe').contentWindow.document.body.offsetHeight.

You can see an example of how to do it on here (note: it is in jQuery, but pretty easy to convert to vanilla JS).

Cross domain iframe resizing

If you are hosting the iframe content on yoursite.com, and your customer emebeds the iframe on theirsite.com, it can be tricky to pass messages between them so the child (iframe) from yoursite.com can tell the parent (theirsite.com) to adjust the width or height of the iframe.

You can use window.postMessage to send messages, and have listeners (in JS in the parent (theirsite.com)) to listen & adjust the iframe.

https://github.com/davidjbradshaw/iframe-resizer is a good example library

Security considerations

(this is not a comprehensive list of security issues with iframes)

  • the iframe tag has has a lot of attributes you can set, like allowfullscreen, allowowpaymentrequest etc.
  • There is also allow which accepts a string of allowed permissions (like microphone access). See permissions policy on mdn
  • sandbox attribute is supported in most modern browsers, and requests heightened security settings.
  • csp (<iframe csp="...">) can be used to set the Content Security Policy for an embedded iframe document
  • Be sure to understand CSP.
  • You might come across errors like Refused to display 'https://yoursite.com' in a frame because it set 'X-Frame-Options' to 'deny'. if you set it up incorrectly
  • Use HTTPS.
  • Be sure to check your CORS config.

Other considerations

  • If you are embedding images or other licensed content, be sure to check if you have the rights to do so.
  • If you are embedding an iframe on your own site then it can make accurate analytics a bit tricky. You might need to send analytics events (like when buttons are clicked) to the parent so it gets tracked correctly.

Other options apart from iframes

  • <object> and <embed> have existed for years, but they are not very common now. They were useful when we worked with Flash objects. You can emebed PDFs with <object>... but they work just as fine in <iframe>s too.
  • web components are a possible option. They are sandboxed, and its safe to make CSS or JS changes to the content in a web component. They are less supported (although most modern browsers will have no problems with them). They also have the advantage of being able to adjust the size/height. This can also result in smaller load sizes (depending on your app/embed of course)