iFrame Resizer & Google Apps Script Web Apps

I recently built a Google Apps Script web app so people can easily ask me questions.
In this process I came across an interesting issue while embedding the web app:
The Problem
It's really hard to get an iFrame (the container for an embedded web app) to accommodate content with variable height.
I'll show you.
Here's the HTML used to embed simple app that has some text and a collapsible div element:
<iframe width=100% src="https://script.google.com/a/kierandixon.com/macros/s/AKfycbzrn_8wWNB-_9LXvHfOBXaESbDWbyX5_WbzSaJK_J1NRMbIWQ2Lq4ed7CQKDXnZTJXa/exec"></iframe>
And here's that code providing the webapp (click where it says):
As the content expands, the iFrame's height remains the same and a scrollbar appears.
This makes the content almost unusable (especially in more complex apps).


FREE RESOURCE
Google Sheets Cheat Sheet
12 exclusive tips to make user-friendly sheets from today:

You'll get updates from me with an easy-to-find "unsubscribe" link.
Possible Solution
What if you just fix the height of the iFrame like this:
<iframe width=100% height=460px src="https://script.google.com/a/kierandixon.com/macros/s/AKfycbzrn_8wWNB-_9LXvHfOBXaESbDWbyX5_WbzSaJK_J1NRMbIWQ2Lq4ed7CQKDXnZTJXa/exec"></iframe>
As you can see, doing this works but it also:
1. Leaves empty white space
This isn't too bad for this simple app. But what if there were multiple collapsible elements of varying heights or hidden validation messages for a form.
You'd need to account for all of these variables and make the iFrame ridiculously tall.
2. Doesn't make the iFrame responsive
As the content of the iFrame is squashed for smaller screens it gets taller (particularly text elements).
Fixing the height of the iFrame will eventually lead to the same problem seen above.
Best Solution
The solution I found is iFrame Resizer by David J. Bradshaw:
However, the code that comes out of the box doesn't work for us.
David believes the implementation of iFrame Resizer with a Google Apps Script web app to be an edge case.
That means it's unlikely that it will be directly supported in the future.
But... you never know.
In the meantime, David gave an amazing answer to a Stack Overflow question about this exact situation.
He made some recommendations on how to alter iFrame Resizer to work with a Google Apps Script web app.
Let's do it.
Download iFrame Resizer Files
You'll need a copy of two files from here:
- iframeResizer.js
- iframeResizer.contentWindow.js
Get the .js versions not the .min.js versions. Making the required changes is much easier without minification.
Make The Changes
1. iframeResizer.js
Change line 850 from:
iframe.contentWindow.postMessage(msgId + msg, target)
To:
window.gasFrame.postMessage(msgId + msg, target)
Then comment out the if statement that starts at line 1434, changing:
if (typeof define === 'function' && define.amd) {
define([], factory)
} else if (typeof module === 'object' && typeof module.exports === 'object') {
// Node for browserfy
module.exports = factory()
}
To:
/*
if (typeof define === 'function' && define.amd) {
define([], factory)
} else if (typeof module === 'object' && typeof module.exports === 'object') {
// Node for browserfy
module.exports = factory()
}
*/
Make sure not to comment out anything else.
2. iframeResizer.contentWindow.js
Change line 1059 from:
undefined !== customHeight ? customHeight : getHeight[heightCalcMode]()
To:
undefined !== customHeight ? customHeight : Number(getHeight[heightCalcMode]()) + 8
The 8 here could change depending on your web app.
Increase this number if the adjusting iFrame still cuts off content.
Upload The Files
Place these edited files on your web server so that you can access them in your code.
Add To Your Web App
With your files uploaded you're ready to change the code in your Google Apps Script web app.
At the bottom of the HTML file your web app delivers, include the following before the closing </body> tag:
<script src="https://kierandixon.com/js/iframeResizer.contentWindow.js"></script>
<script>
top.postMessage('gasFrame', '*');
</script>
Now it's just placing some code on your website.
Add To Your Website
Lastly, on the page you want your embedded web app to appear you need to:
- Reference the web app in an iframe element with an id
- Include a reference to the modified iframeResizer.js file on your server
- Include an additional script to handle the changes you've made that references the id of your iframe
Here's all of that in one:
<iframe width=100% id="flexible" src="https://script.google.com/a/kierandixon.com/macros/s/AKfycbx3o-mjVzmMz2F_H5phQV83KpCPl0zGiymsCeLefM6ZT5DJ7bjYkk5ujyQybI2QZrnbwQ/exec"></iframe>
<script src="https://kierandixon.com/js/iframeResizer.js"></script>
<script>
window.addEventListener(
'message',
(event) => {
if (event.data === 'gasFrame') {
window.gasFrame = event.source;
iFrameResize({
log: false,
checkOrigin: false
}, '#flexible');
}
},
false
);
</script>
Making It Look Even Better
To make your embedded web app look even better than it does you can include a frameborder=0 attribute with your iframe element:
<iframe width=100% id="flexible" frameborder=0 src="https://script.google.com/a/kierandixon.com/macros/s/AKfycbzrn_8wWNB-_9LXvHfOBXaESbDWbyX5_WbzSaJK_J1NRMbIWQ2Lq4ed7CQKDXnZTJXa/exec"></iframe>
This removes the default beveled iFrame border and makes it appear simply as part of the page:
I also like to go the extra mile and add this CSS in the <head> tag of the web app:
<style>
::-webkit-scrollbar {
width: 0px;
}
</style>
Including this means that on some modern browsers the scrollbar won't appear as the iFrame expands.
Troubleshooting
If you can't seem to make things work, check your console and read through the documentation and troubleshooting guide.


FREE RESOURCE
Google Sheets Cheat Sheet
12 exclusive tips to make user-friendly sheets from today:

You'll get updates from me with an easy-to-find "unsubscribe" link.
