Jacob Paris
← Back to all content

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>
Professional headshot

Hi, I'm Jacob

Hey there! I'm a developer, designer, and digital nomad with a background in lean manufacturing.

About once per month, I send an email with new guides, new blog posts, and sneak peeks of what's coming next.

Everyone who subscribes gets access to the source code for this website and every example project for all my tutorials.

Stay up to date with everything I'm working on by entering your email below.

Unsubscribe at any time.