How we made Elm and Google Translate work together

Google Translate can crash Elm, or any Virtual DOM based page. This is how we worked around it using a nifty little JavaScript hack.

Google Chrome offers to translate pages by default:

Google Chrome offers to translate pages via a popup in the address bar.

Pretty handy if the page does not offer any language you understand well!

If you use that feature on a page written in Elm, the JS console starts to fill up with “replaceData is not a function” errors. Buttons stop working and the page renders in weird ways. Similar issues occur in other Virtual DOM based frameworks too.

This was by far the most common error in our error reporting service.

Was the most common error. Let me share our workaround:

HTMLFontElement.prototype.replaceData =
  function replaceData(_0, _1, string) {
    this.parentNode.replaceChild(
      document.createTextNode(string),
      this
    );
  };

What a lovely hack!

This is how it works:

Google Translate replaces every text node in the DOM with a <font> tag containing at least one more <font> tag – one for each sentence. For example:

<span>Insurello. Rätt ersättning till alla</span>

Google Translate turns that into:

<span><font><font>Insurello. </font><font>The right compensation for everyone</font></font></span>

When Elm re-renders, it’s going to think that the <span> contains one single text node and might call .replaceData() on it to change its text. However, there’s a <font> element there instead now and elements don’t have a .replaceData() method. Hence the errors in the console. (Other methods, such as .removeChild() work fine with text nodes.)

The hack adds a .replaceData() method to <font> elements. The method replaces the <font> tag with a text node. Google Translate then detects the new text node, translates its text and replaces it with new <font> tags.

This assumes that only Elm will call font.replaceData() and only with the specific arguments that Elm always does, and that it will only happen on Google Translate <font> tags. But it works great for us!

We used to have over 20 000 “replaceData” errors per month, impacting almost a hundred users. With the hack we’re down to about zero. I hope this helps your Elm app too!