In modern JavaScript web development workflows, it’s common to install JavaScript via npm packages. However, there are situations where you may need to include an external JavaScript file, which can be a bit tricky with modern tools. In this blog post, we’ll explore how to include an external JavaScript file in a Gatsby site.

The Challenge

Let’s say we want to embed a video from Wistia in our Gatsby site. Wistia provides an HTML snippet to embed the video. Here’s an example:

<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>

Embedding this snippet in a “normal” HTML site would be simple. However, in a Gatsby site, which is a React component, it requires a different approach.

The Solution

After exploring some plugins without success, I found a “hacky” solution that worked well for me. First, I converted the HTML code into JSX, making sure to properly convert the HTML attributes (class becomes className, aria-hidden becomes ariaHidden) and inline styles. You can use a tool like magic.reactjs.net/htmltojsx to quickly convert the code.

Next, I added the converted JSX code to the gatsby-browser.js file. This file is responsible for manipulating the browser’s behavior in a Gatsby site. Here’s an example of how to add the necessary scripts 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");
  };
};

In this code, we define a function addScript that dynamically adds a <script> tag to the page. We then use the window.onload event to execute the addScript function with the URLs of the Wistia scripts we want to include.

This solution may not be the most elegant, but it allows us to include external JavaScript files in a Gatsby site while still maintaining control over what’s happening.

I hope this solution helps you in your Gatsby development projects. Feel free to explore other approaches and plugins to find the one that suits your specific needs. Happy coding!