Go to Qubit

Opentag documentation

Document.write

The JavaScript functions document.write and document.writeln synchronously put content on the page, and can cause a lot of mischief.

Overview

document.write is a fickle thing when it comes to asynchronously loading tags. While it is considered bad practice by the developer community, a lot of tag vendors still encourage its usage.

This article details how Opentag handles document.write in the different use-cases, although if you follow our best practice, you shouldn’t need to know any more.

How Opentag handles it

The annoying thing about document.write is it only exists while the page is loading – after the page has finished rendering the result of calling this function is browser dependent – some browsers will stop loading the page, some will try to open a new page, some will just ignore it.

These calls are used for one of two reasons:

  • It is a legacy system and is used without given any thought to asynchronous loading
  • It is a system that wants to change the page right away (A/B testing tools may fall into this category)

On the bright side, many tags are migrating to have a asynchronous build, so hopefully this problem will (slowly) go away. Until then, how do we solve the problems document.write presents?

Because it is not able to be called after the page loads it means that you either have to stop the page and load it (by yourself using document.write!) or by replacing document.write with your own function.

Opentag does both depending upon the scenario.

When Opentag itself is on the page synchronously (ie the async and defer attribute keys have been removed from the script tag) and your scripts use document.write, then we will load your scripts with document.write, ensuring synchronicity (ie we stop the page while the script loads). This has the downside that it will slow down your page from loading. However, for A/B testing software this can be a good thing!

If Opentag is async as we generally advise, we try to be smart about document.write by overriding it with a function. When our script has finished loading we then see what has been written to the page and add it in.

A few problems may occur with this, in which case you may need to fall back to the synchronous method to solve the problem:

1. The script that is written itself uses document.write:

<script>
  document.write("<scri" + "pt>document.write('this is annoying');</scr"+"ipt");
</script>

2. The script you are using relies on the output of document.write right away:

<script>
  document.write("<div id='el_id'></div>");
  document.getElementById("el_id");
</script>

3. We handle the case where a script loaded via URL uses document.write, however we do not handle the case where the script is loaded by HTML:

<script>
  var x = document.createElement("script");
  x.src="<some script that loads document.write>";
  document.body.appendChild(x);
</script>

Deferred document.write

One other issue that may be encountered is when you have other scripts on the page that use document.write. This is often the case if you have advertisements on your page. In this case, Opentag’s overriden version of document.write collides with the calls to it outside of Opentag. The solution to this is to use the “defer document.write” option under the Container’s options. This prevents all scripts which use document.write within Opentag from firing until the page itself has rendered.

Tip: As you can see scripts using document.write are quite complicated. This is another big benefit of using the tag library rather than custom scripts – we’ve already checked the tags for document.write, reducing any potential issues.

Was this helpful?