How to programmatically add script tags to your React application

Bjorn Krols

Bjorn Krols

Published on
24 May 2021

Not all tools distribute their code via NPM; services such as Twitter, Google Maps, reCAPTCHA and PayPal still require you to load scripts from their CDN. Loading external scripts in your React application can be as easy as adding a script tag to the HTML file that loads your React bundle; but this isn't always easy or possible. In this article you will learn how to add script tags programmatically, using JavaScript and standard DOM APIs.

Adding the script to the DOM

  1. Create a new element of type script.
  2. Set its src attribute.
  3. Give it a recognizable id.
  4. Set its async attribute to true, this ensures the file gets downloaded asynchronously and then executed as soon as it's downloaded (scripts that are not render-blocking will make your website load faster).
  5. Append it to the body.
const addScript = ({ src, id, onLoad }) => {
  const existing = document.getElementById(id);
  if (existing) {
    return existing;
  } else {
    const script = document.createElement("script");
    script.src = src;
    script.id = id;
    script.async = true;
    script.onload = () => {
      if (onLoad) {
        onLoad();
      }
    };
    document.body.appendChild(script);
    return script;
  }
};

addScript({
  src: `https://platform.twitter.com/widgets.js`,
  id: "twitter-script",
  onLoad: () => {
    console.log("Twitter script loaded!");
  },
});

Removing the script from the DOM

const removeScript = ({ id }) => {
  const script = document.getElementById(id);
  if (script) {
    document.body.removeChild(script);
  }
};

removeScript({
  id: "twitter-script",
});

React hook version

The useEffect hook lets you perform side effects in function components, the hook will run the passed function every time something affects the component (like a state change). Since we only want to add the script tag once, we need to pass the hook an empty array as its second argument. We also return a function containing the cleanup code.

useEffect(() => {
  const script = addScript({
    src: `https://platform.twitter.com/widgets.js`,
    id: "twitter-script",
    onLoad: () => {
      console.log("Twitter script loaded!");
    },
  });
  return () => removeScript({ id: script.id });
}, []);

Class component version

Setup code goes into componentDidMount, cleanup code goes into componentDidUnmount.

class Component extends React.Component {
  componentDidMount() {
    addScript({
      src: `https://platform.twitter.com/widgets.js`,
      id: "twitter-script",
      onLoad: () => {
        console.log("Twitter script loaded!");
      },
    });
  }

  componentDidUnmount() {
    removeScript({
      id: "twitter-script",
    });
  }
}

Subscribe to our newsletter

The latest news, articles, and resources, sent to your inbox weekly.

More like this