10

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?

Ashh
  • 44,693
  • 14
  • 105
  • 132
  • 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 ? – Moti Korets Apr 16 '18 at 07:09
  • I hope you know that react uses a virtual DOM. – Mohhamad Hasham Apr 16 '18 at 07:17
  • @AshishChoudhary don't append it to this.instance. Try append it to the document directly. – digitake Apr 16 '18 at 07: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` ? – Moti Korets Apr 16 '18 at 07: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` – digitake Apr 16 '18 at 07:30

8 Answers8

18

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>')
Ashh
  • 44,693
  • 14
  • 105
  • 132
  • 3
    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'); } – Miek Jan 20 '19 at 22:26
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>
}
Marcos
  • 1,043
  • 10
  • 15
  • 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? – Dhanendra Kumar Aug 09 '22 at 08:16
  • 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', ...`. – Marcos Aug 11 '22 at 02:08
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');
  }
Sushil
  • 2,324
  • 1
  • 27
  • 26
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>
Alex Hughes
  • 99
  • 1
  • 8
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

harsh tibrewal
  • 785
  • 6
  • 21
0

Update 2022

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

nachtigall
  • 2,447
  • 2
  • 27
  • 35
0

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]);
Carlos Julio
  • 290
  • 3
  • 11
-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

Yash Thakur
  • 1,172
  • 7
  • 14
  • 1
    Links tend to change over time, please avoid adding a link but rather post the highlights from the link here as an answer – Technotronic Apr 24 '20 at 09:29
  • 1
    From "How do I write a good answer" (https://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. – Technotronic Apr 30 '20 at 10:31