How to Replace an iFrame with a Message When Your Viewer is Offline

An iFrame lets you embed a website inside of another HTML document. It’s often used to add online content to otherwise offline publications. When a viewer is offline, the iframe fails completely, and the author doesn’t have control of what is displayed.

So how do we go about fixing that?

The onerror Event

Note: The onerror event no longer seems to fire when used with an iframe. I’m leaving the article in place in case it helps with understanding the issue, but this is probably a better solution.

Adding an onerror attribute looked like a promising solution…at first…because I was only testing in Firefox.

I tested 2 techniques

  1. Setting the srcdoc attribute, which lets you apply HTML code as the iframe content.
  2. Using the jQuery replaceWith method to replace the iframe tag.

Both worked quite well…

first offline test

…until I tested Chrome and Safari.

Depending on the URL I used, I either got a silent error with an empty iframe, or content generated by the browser.

Adding the navigator.onLine test

Newer browsers (including Chrome and Safari) support the navigator.onLine property. So I added the following onload attribute to the iframe tag.

onload="if(navigator.onLine===false) eval(this.getAttribute('onerror'));"

Since I’m lazy and I don’t like to re-write (and re-writing introduces opportunities for mistakes), if the browser is offline, this will execute the code that was already written for the onerror attribute.

I used the strict equivalence operater (===), as opposed to the equivalence operator (==), to ensure that this would not be triggered if navigator.onLine was undefined, which would be the case in an older browser.

Putting it all together

This jsfiddle has the source code for 4 different examples.

offline iframe working examples

I purposely wrote the code so that everything could be included with the iframe itself, because many of our in5 customers are pasting the iframe embed code into their InDesign documents for digital publication.

Alternatively, you could write a block of code that handles an entire document full of iframes.

Handling all iframes with a single block of code

This could also be done with in5 content, by attaching the JavaScript as an external resource.

Here’s how you would do the same exactly thing, but with a single code block (i.e., not hand-altering every iframe in your document).
$(function(){
$('iframe').each(function(index,elem){
$(elem).attr('onerror',"'srcdoc','<p>You need to be online to view this content.</p>');").attr('onload', "if(navigator.onLine===false) eval(this.getAttribute('onerror'));"); }); });

Caution: Using this global technique, you may also want to check to make sure you’re only altering iframes where the src attribute is online content (e.g., contains ://).

This simple message is just a proof-of-concept. You could also design an image behind your iframe and hide the iframe when offline. In that case you could use $(this).hide() if jQuery is available or this.style.display=”hidden” with plain, vanilla JavaScript.

Hope that helps you to handle your offline content!

Get updates from Ajar Productions

Sign up today and get the InDesign Split Text premium extension for free!

Unsubscribe at any time. Powered by ConvertKit

Join the Conversation

  1. Joe Web says:

    your post addresses the iframe problem i am trying to solve EXACTLY!

    unfortunately, your solution posted at https://jsfiddle.net/justinputney/jpaaytc4/2/ does not work in any browsers.

    i see you posted this article back in 2016. is there a chance you could revisit it any post a working update?

    thank you!

    1. Justin says:

      It looks like the onerror attribute no longer works with iframes, though it does work with img tags:
      https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_ev_onerror

      This solution is probably a better approach at this point:
      https://stackoverflow.com/questions/9534001/want-to-call-a-function-if-iframe-doesnt-load-or-loads/9576180#9576180

Leave a comment

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