12

I am having following script file

<script language="javascript">

document.write('<script language="javascript" src="http://tickettransaction.com/?bid='+bid+'&sitenumber='+site+'&tid=event_dropdown" ></' + 'script>');
</script>

I follow this Adding script tag to React/JSX but it does not work for me...

How do I load the script in my react component?

5
  • Need more context of where this script is running from to solve this. Also what do you mean how to load the script in my react component ? Commented Apr 16, 2018 at 7:09
  • I hope you know that react uses a virtual DOM. Commented Apr 16, 2018 at 7:17
  • @AshishChoudhary don't append it to this.instance. Try append it to the document directly. Commented Apr 16, 2018 at 7:20
  • Try change the url to https:// (with s) see if it helps. So what error do you get when you do document.body.appendChild from componentDidMount ? Commented Apr 16, 2018 at 7:30
  • @AshishChoudhary your script is actually trying to use document.write after it loaded, which isn't allowed. you might need to either (1) load it by embedded to HTML. or (2) replace all document.write in the script with appendChild Commented Apr 16, 2018 at 7:30

8 Answers 8

19

After a lots of R&D finally I found my solution.

I have used npm postscribe to load script in react component

postscribe('#mydiv', '<script language="javascript" src="http://tickettransaction.com/?bid='+bid+'&sitenumber='+site+'&tid=event_dropdown"></script>')
Sign up to request clarification or add additional context in comments.

1 Comment

Holy cow, thank you for this post! I spent more time than I care to admit trying to get a native amazon ad to load into a react component, this did the trick. Anyone that may be looking here for the same thing, set your componentDidMount like this: componentDidMount() { postScribe('#YourDivId','copy + paste amazon code here'); }
13

A 2021 TypeScript example using functional components that works with NextJS

(ensures code only runs client-side)


declare global {
  interface Window {
    hbspt: any
  }
}

export default function Contact() {
  useEffect(() => {
    if (window && document) {
      const script = document.createElement('script')
      const body = document.getElementsByTagName('body')[0]
      script.src = '//js.hsforms.net/forms/v2.js'
      body.appendChild(script)
      script.addEventListener('load', () => {
        window.hbspt.forms.create({
          // this example embeds a Hubspot form into a React app but you can tweak it for your use case
          // any code inside this 'load' listener will run after the script is appended to the page and loaded in the client
        })
      })
    }
  }, [])

  return <div id="hbspt-form" className="p-5"></div>
}

2 Comments

Is there any way by which we can skip the event listener "load". Like i added the script on parent page and wants to use the same script for multiple forms later in the child components?
Not exactly sure what you mean but you could use parentScript = document.getElementsByClassName(...) or something similar to get a reference to the script you added in the parent page and then you'd use the 'load' event listener same as here but on that reference — e.g. parentScript.addEventListener('load', ....
8

the following method is worked for me. try, hope it will work for you. basically, you can create a script tag and append it to the body tag. like this--

var tag = document.createElement('script');
tag.async = true;
tag.src = 'THE PATH TO THE JS FILE OR A CDN LINK';
var body = document.getElementsByTagName('body')[0];
body.appendChild(tag);

you can use this on a life cycle hook of react like this.

componentDidMount() {
    var loadScript = function (src) {
      var tag = document.createElement('script');
      tag.async = false;
      tag.src = src;
      var body = document.getElementsByTagName('body')[0];
      body.appendChild(tag);
    }

    loadScript('PATH TO THE JS FILE OR CDN URL');
  }

Comments

2

I recommend using React Helmet. I've used it on a couple of Create-React-Apps, and it allows you to write actual script tags combined with vanilla JS.

It makes the process a lot smoother. So for you it'd be something like this once you've imported React Helmet.

<script language="javascript" src='http://tickettransaction.com/?bid='+ bid + '&sitenumber='+ site +'&tid=event_dropdown' ></ script>

Comments

1

This came to my rescue. This is the easiest way to load Script Tags

https://www.npmjs.com/package/react-script-tag

import ScriptTag from 'react-script-tag';

const Demo = props => (
<ScriptTag src="/path/to/resource.js" />
);

There are other ways to do this too :

https://medium.com/better-programming/4-ways-of-adding-external-js-files-in-reactjs-823f85de3668

1 Comment

The author has since marked this as "abandoned and unmaintained" npmjs.com/package/react-load-script
1

Update 2022

Use https://usehooks-ts.com/react-hook/use-script. This also returns status and allows props like removeOnUnmount.

Comments

1

Most of packages to do the job are outdated at the date. I found a solution that maybe can be useful for someone and it´s using a hook with the advantage you can control the state and take action based on it.

import { useEffect, useState } from 'react';

export const useExternalScript = (url) => {
    let [state, setState] = useState(url ? "loading" : "idle");

    useEffect(() => {
        if (!url) {
            setState("idle");
            return;
        }

        let script = document.querySelector(`script[src="${url}"]`);

        const handleScript = (e) => {
            setState(e.type === "load" ? "ready" : "error");
        };

        if (!script) {
            script = document.createElement("script");
            script.type = "application/javascript";
            script.src = url;
            script.async = true;
            document.body.appendChild(script);
            script.addEventListener("load", handleScript);
            script.addEventListener("error", handleScript);
        }

        script.addEventListener("load", handleScript);
        script.addEventListener("error", handleScript);

        return () => {
            script.removeEventListener("load", handleScript);
            script.removeEventListener("error", handleScript);
        };
    }, [url]);

    return state;
};

Use it is simple as do:

const externalScript = 'https://player.live-video.net/1.6.1/amazon-ivs-player.min.js';
const scriptStatus = useExternalScript(externalScript);

useEffect(() => {
    if (scriptStatus === 'ready') {
        // Do something with it
    }
}, [scriptStatus]);

1 Comment

I much prefer a hook like this than yet another dependency
-4

Update 2022 for Class based as well as Functional components.

You can create a function as below and then use it inside componentDidMount:

function loadScript(url, callback){

    let script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState){  //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" ||
                    script.readyState == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        };
    } else {  //Others
        script.onload = function(){
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

// For class based components
componentDidMount() {
    loadScript("scriptUrl", callback());
}

// For functional components
useEffect(() => {
    loadScript("scriptUrl", callback());
}, [])

Source: add third-party js library to Create React App

2 Comments

Links tend to change over time, please avoid adding a link but rather post the highlights from the link here as an answer
From "How do I write a good answer" (stackoverflow.com/help/how-to-answer) > Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.