Loading an external JS file using Gatsby

🆕 🔜 Check this out if you dream of running a solo Internet business 🏖️

In the modern JavaScript Web Development workflow it’s quite common to install JavaScript via npm packages.

Sometimes however we must include an external JavaScript file, and modern tools might make this a little difficult.

In particular I had the need to include a video from Wistia in my site, and after a quick look everything looked quite more complicated than I wanted.

Wistia gave me this HTML snippet to embed:

<script src="https://fast.wistia.com/embed/medias/VIDEOURL.jsonp" async></script><script src="https://fast.wistia.com/assets/external/E-v1.js" async></script><div class="wistia_responsive_padding" style="padding:56.25% 0 0 0;position:relative;"><div class="wistia_responsive_wrapper" style="height:100%;left:0;position:absolute;top:0;width:100%;"><div class="wistia_embed wistia_async_VIDEOURL seo=false videoFoam=true" style="height:100%;position:relative;width:100%"><div class="wistia_swatch" style="height:100%;left:0;opacity:0;overflow:hidden;position:absolute;top:0;transition:opacity 200ms;width:100%;"><img src="https://fast.wistia.com/embed/medias/VIDEOURL/swatch" style="filter:blur(5px);height:100%;object-fit:contain;width:100%;" alt="" aria-hidden="true" onload="this.parentNode.style.opacity=1;" /></div></div></div></div>

On a “normal” HTML site, maybe built with Hugo like I usually do, it would be dead simple.

I’d just add this code to my page.

But in a Gatsby page, which is a React component?

I looked at some plugins but no one really did what I wanted.

The solution is perhaps a bit “hacky”, but worked like a charm and I still feel I have control over what’s happening.

I added the HTML code as JSX, properly converting all the HTML attributes: class -> className, aria-hidden -> ariaHidden, and the styles - use a tool like https://magic.reactjs.net/htmltojsx.htm to make it quick.

Then I added this code to the gatsby-browser.js file to add the scripts I needed, on page load:

const addScript = url => {
  const script = document.createElement("script")
  script.src = url
  script.async = true
  document.body.appendChild(script)
}

export const onClientEntry = () => {
  window.onload = () => {
    addScript("https://fast.wistia.com/embed/medias/9rvl8vgrzg.jsonp")
    addScript("https://fast.wistia.com/assets/external/E-v1.js")
  }
}