Adding script tag to React/JSX

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 (

People




);
}
};

I have also tried:

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.

Solutions/Answers:

Solution 1:

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 = "https://use.typekit.net/foobar.js";
    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.

Related:  How to properly add 1 month from now to current date in moment.js

Solution 2:

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

Solution 3:

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="https://use.typekit.net/foobar.js"></script>
                <script>try{Typekit.load({ async: true });}catch(e){}</script>
            </Helmet>
            ...
        </div>
    );
  }
};

https://github.com/nfl/react-helmet

Solution 4:

If you need to have <script> block in SSR (server-side rendering), an approach with componentDidMount will not work.

You can use react-safe library instead.
The code in React will be:

import Safe from "react-safe"

// in render 
<Safe.script src="https://use.typekit.net/foobar.js"></Safe.script>
<Safe.script>{
  `try{Typekit.load({ async: true });}catch(e){}`
}
</Safe.script>

Solution 5:

I created a React component for this specific case: https://github.com/coreyleelarson/react-typekit

Related:  When a user closes a

Just need to pass in your Typekit Kit ID as a prop and you’re good to go.

import React from 'react';
import Typekit from 'react-typekit';

const HtmlLayout = () => (
  <html>
    <body>
      <h1>My Example React Component</h1>
      <Typekit kitId="abc123" />
    </body>
  </html>
);

export default HtmlLayout;

Solution 6:

The answer Alex Mcmillan provided helped me the most but didn’t quite work for a more complex script tag.

I slightly tweaked his answer to come up with a solution for a long tag with various functions that was additionally already setting “src”.

(For my use case the script needed to live in head which is reflected here as well):

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

      const scriptText = document.createTextNode("complex script with functions i.e. everything that would go inside the script tags");

      script.appendChild(scriptText);
      document.head.appendChild(script);
  }