← Back to Cheatsheets

Send messages from an embedded iframe to the parent page

This is a helper script to allow an embedded iframe to communicate with its parent page.

Place this on the page that contains the <iframe

The script

  • Listens for triggers emitted by application
  • Triggers scrolling on parent page
  • Triggers positions and resize iframe to fit content
  • Triggers opening of new pages
  • Passes UTM codes into iframe via URL query
js
1;(function (frameId) {
2 let connected = false
3
4 if (document.readyState === "loading") {
5 document.addEventListener(
6 "readystatechange",
7 addEventListenersToDocument,
8 )
9 } else {
10 addEventListenersToDocument()
11 }
12
13 function addEventListenersToDocument() {
14 if (connected) return
15
16 // The iframe with the funnel must have the following ID
17 const portal =
18 document.getElementById(frameId)
19
20 // Set initial height to reduce jarring size changes
21 portal.style["min-height"] = "100vh"
22
23 window.addEventListener(
24 "message",
25 function (e) {
26 // Resize iframe to fit contents
27 if (
28 e.data.type &&
29 e.data.type === "size"
30 ) {
31 portal.style["min-height"] =
32 e.data.height + "px"
33 }
34
35 // Scroll parent page to top
36 if (
37 e.data.type &&
38 e.data.type === "scrolltop"
39 ) {
40 document.body.scrollIntoView(
41 e.data.options,
42 )
43 }
44
45 // Scroll parent page by X (Up, Down, Left or Right)
46 if (
47 e.data.type &&
48 e.data.type === "scrollby"
49 ) {
50 // Make movements better on mobile
51 e.data.options.top =
52 window.innerHeight <
53 e.data.options.top
54 ? window.innerHeight / 3
55 : e.data.options.top / 2
56 // Need to check to see if the browser supports smooth scroll
57 // otherwise use legacy scroll
58 if (
59 "scrollBehavior" in
60 document.documentElement.style
61 ) {
62 window.scrollBy(e.data.options)
63 } else {
64 window.scrollBy(
65 e.data.options.left,
66 e.data.options.top,
67 )
68 }
69 }
70
71 // Click link inside of iframe
72 if (
73 e.data.type &&
74 e.data.type === "link"
75 ) {
76 window.open(
77 "./" +
78 e.data.path.replace(
79 new RegExp("^/"),
80 "",
81 ),
82 "_blank",
83 )
84 }
85 },
86 )
87
88 // Extract utm codes from query string
89 const parentUrl = new URL(
90 window.location.href,
91 )
92 const urlCodes = Object.fromEntries(
93 Array.from(
94 parentUrl.searchParams.entries(),
95 ).filter(([key]) => key.startsWith("utm_")),
96 )
97
98 const utmCodes = {
99 ...urlCodes,
100 }
101
102 // Assign utm codes to iframe query string
103 const portalUrl = new URL(portal.src)
104
105 Object.entries(utmCodes).forEach(
106 ([key, code]) => {
107 portalUrl.searchParams.append(key, code)
108 },
109 )
110
111 portal.src = portalUrl.href
112 connected = true
113
114 document.removeEventListener(
115 "readystatechange",
116 addEventListenersToDocument,
117 )
118 }
119})("FRAME_ID")
120

Usage

Replace 'FRAME_ID' at the bottom of the script with the id of the iframe you want to embed.

Embed the iframe with the same ID and the following script

<script src="./iframe.js"></script>
<iframe
id="FRAME_ID"
src="https://example.com"
style="border: 0px; width: 100%; margin: 1rem 0rem 2rem; min-height: 45rem;"
allowfullscreen="true"
sandbox="allow-same-origin allow-scripts allow-top-navigation-by-user-activation allow-popups allow-popups-to-escape-sandbox allow-forms"
scrolling="no"
width="100%"
height="100%"
></iframe>