Adding Script Tag to React/Jsx

I have a relatively straightforward issue of trying to add inline scripting to a React component. What I have so far:

'use strict';

import '../../styles/pages/people.scss';

import React, { Component } from 'react';
import DocumentTitle from 'react-document-title';

import { prefix } from '../../core/util';

export default class extends Component {
    render() {
        return (
            <DocumentTitle title="People">
                <article className={[prefix('people'), prefix('people', 'index')].join(' ')}>
                    <h1 className="tk-brandon-grotesque">People</h1>
                    
                    <script src=""></script>
                    <script dangerouslySetInnerHTML={{__html: 'try{Typekit.load({ async: true });}catch(e){}'}}></script>
                </article>
            </DocumentTitle>
        );
    }
};

I have also tried:

<script src=""></script>
<script>try{Typekit.load({ async: true });}catch(e){}</script>

Neither approach seems to execute the desired script. I'm guessing it's a simple thing I'm missing. Can anybody help out?

PS: Ignore the foobar, I have a real id actually in use that I didn't feel like sharing.

4

27 Answers

Edit: Things change fast and this is outdated - see update


Do you want to fetch and execute the script again and again, every time this component is rendered, or just once when this component is mounted into the DOM?

Perhaps try something like this:

componentDidMount () {
    const script = document.createElement("script");

    script.src = "";
    script.async = true;

    document.body.appendChild(script);
}

However, this is only really helpful if the script you want to load isn't available as a module/package. First, I would always:

  • Look for the package on npm
  • Download and install the package in my project (npm install typekit)
  • import the package where I need it (import Typekit from 'typekit';)

This is likely how you installed the packages react and react-document-title from your example, and there is a Typekit package available on npm.


Update:

Now that we have hooks, a better approach might be to use useEffect like so:

useEffect(() => {
  const script = document.createElement('script');

  script.src = "";
  script.async = true;

  document.body.appendChild(script);

  return () => {
    document.body.removeChild(script);
  }
}, []);

Which makes it a great candidate for a custom hook (eg: hooks/useScript.js):

import { useEffect } from 'react';

const useScript = url => {
  useEffect(() => {
    const script = document.createElement('script');

    script.src = url;
    script.async = true;

    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    }
  }, [url]);
};

export default useScript;

Which can be used like so:

import useScript from 'hooks/useScript';

const MyComponent = props => {
  useScript(');

  // rest of your component
}
19

My favorite way is to use React Helmet – it's a component that allows for easy manipulation of the document head in a way you're probably already used to.

e.g.

import React from "react";
import {Helmet} from "react-helmet";

class Application extends React.Component {
  render () {
    return (
        <div className="application">
            <Helmet>
                <script src=""></script>
                <script>try{Typekit.load({ async: true });}catch(e){}</script>
            </Helmet>
            ...
        </div>
    );
  }
};
7

Further to the answers above you can do this:

import React from 'react';

export default class Test extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    const s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.innerHTML = "document.write('This is output by document.write()!')";
    this.instance.appendChild(s);
  }

  render() {
    return <div ref={el => (this.instance = el)} />;
  }
}

The div is bound to this and the script is injected into it.

Demo can be found on codesandbox.io

6

This answer explains the why behind this behavior.

Any approach to render the script tag doesn't work as expected:

  1. Using the script tag for external scripts
  2. Using dangerouslySetInnerHTML
David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.