How I got an API provider to change their embed code implementation

Luiz Henrique Guerra
5 min readDec 22, 2022
Photo by Ante Hamersmit on Unsplash

I'd like to share this interesting thing that recently happened to me while coding for one of my clients' product. They pay for a service that provides an API with data that is immensely relevant for the product, and there was a new feature they just have made available: a configurable embed solution to display their data right away in the frontend, without the need of writing your own frontend to display the content of the API integration.

Since this feature could be a great time saver for content creators at my client's office, it was made a priority to make it work in their new website (which is the product I mentioned above).

The issue: CWV performance score

Since the website relies on audience to make money, Search Engine Optimization (SEO) is not negotiable. And a big part of it became performance since Google started to use Core Web Vitals (CWV) metrics to help to decide which pages to index first.

So I started by implementing the iframe in the way that was documented: by inserting a script tag in my page. The problem is that the tag would load a very large script file that wasn't even needed in the page first load, because the iframe would only be seen if the user scrolled the page down a little.

The practical solution: lazy loading

Since the script wasn't needed in the first load of the page and I had no control over it anyway, it's loading could just be delayed, avoiding unnecessary requests when the user doesn't get to that section of the page and also not affecting CWV performance score.

The website frontend is made in React, using Next framework. I don't want to get too specific about the technical decisions of my team but these two are important to keep in mind in order to understand how I addressed this problem. With Next we are able to render React components both in the server and client sides, so what I needed to implement was a trigger that would only fire the rendering of the component inserting the provider's script when the user has scrolled the page down to where it was placed.

To achieve that, react-cool-inview was used, but please understand that there is a number of ways to achieve similar results and this detail is not the main point here, it is only informative.

The impact: provider's script not prepared to work properly with lazy loading

When I thought my problems would be solved, there was a big surprise: the iframe didn't render properly anymore. It actually went missing for a while, until I found it bellow every elements on the page. Reading the script that was downloaded, and also a large warning in the browser's console, the cause was clear: the script used document.write() to render its contents.

You might already know how bad a practice it is to use document.write():

From Mozilla Development Network website:

"Warning: Use of the document.write() method is strongly discouraged."

See more at: https://developer.mozilla.org/en-US/docs/Web/API/Document/write#notes

But bad practice or not, why was it at the bottom of the page? My default implementation for loading any script in this website was to use Next's Script component, which does the hard work of correctly placing the script according to the chosen loading strategy. And when we say correctly placing a script tag, we mean either in the <head> or after all content before the closing </body> tag, right? There is no loading strategy for placing the script inline right where I added its code. And because document.write() was being used, the iframe was being rendered right where the script was placed.

The support ticket

The frustration grew too big for me to keep trying, because every iframe we needed to implement so far worked right away. Most embed implementations guide us to add both a script tag and an HTML element with a specific selector in our code, making it possible to control with precision both the script loading strategy and the iframe placing. Any big social media platform, for example, provides either this kind of embed or an iframe, which is even simpler, working very well out of the box. All the effort trying to solve this issue was because of just one provider of embedded content (out of at least six). I actually thought about giving up and making my own implementation for visualizing that data, using the API solution directly and bypassing the embed.

But I also thought it could be worth my while if I tried to explain the issues in their support platform. Maybe I missed something. In the initial message I described the situation and also explained about using a framework implementation to load the scripts. And in the first answer, the support team insisted I implemented the script exactly like described in the docs, then it would work.

The new strategy

Next's Script component was then switched to a native HTML script tag rendered in the middle of the page content, like in the example provided. But because it was being lazy loaded, document.write() wasn't being called anymore, and the following error was popping up in the browser console:

Failed to execute ‘write’ on ‘Document’: It isn’t possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

I actually still don't understand how it worked when I was using the Script component (even if at page bottom). Maybe it forces document.open() and document.close() under the hood.

The dead end

Either way I was still not able to see a working example that would load in the reserved area and not impact first load performance. The situation was bugging me a lot at this point. Why would they create an embed script that can't be loaded following web's best practices? And also why such an outdated solution like document.write() is being used? And why spend my time and my client's money on a solution that was sold as plug and play?

Then it occurred to me that if I could get passed all the frustration, maybe I could tell all of this to them in a way that might leverage change.

The change

After exchanging some more messages in the support ticket, I told the support guys about the problem with document.write() and how hard it was to implement the embed. I also sent the Mozilla notes about it. And they agreed to change their code to stop using it!

I'd say it is not ideal yet, because we still need to print the script tag exactly where the embed needs to be rendered and bypass Next's default solution for loading scripts. But it worked! And every embed script we need can be lazy loaded, so "not ideal" is working actually pretty well for now.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Luiz Henrique Guerra
Luiz Henrique Guerra

Written by Luiz Henrique Guerra

Just trying to make some thoughts last. I like to write about software development and agility

No responses yet

Write a response