Gatsby: How do you insert an external script using gatsby-browser?

Created on 11 Jan 2019  路  14Comments  路  Source: gatsbyjs/gatsby

Summary

I would like to external scripts that would work after the React Dom is rendered. In addition, I would only like it loaded on specific pages.

Relevant information

I'm trying to load an external script that uses the global document. It works locally but I keep getting a WebpackError: ReferenceError: document is not defined when deployed on Netlify. I've tried using React-Helmet but I was running into this issue https://github.com/nfl/react-helmet/issues/324 .

File contents (if changed)

gatsby-config.js: N/A
package.json: N/A
gatsby-node.js: N/A
gatsby-browser.js

const perlinNoise = require('./static/perlin-noise')

const insertJS = () => {
  const addJS = (src) => {
    const s = document.createElement(`script`)
    s.type = `text/javascript`
    s.src = src
    document.getElementsByTagName(`head`)[0].appendChild(s)
  }

  addJS(perlinNoise)
}

exports.onInitialClientRender = () => {
  insertJS()
}

gatsby-ssr.js: N/A

stale? question or discussion

Most helpful comment

Uncaught TypeError: Cannot read property 'fn' of undefined

Script tags should be placed at the end of page.

Whereas Helmet and gatsby-plugin-load-script try to append script into the head (see link).

Basically, you just need a gatsby-ssr.js file like this, no need plugin at all.

Create gatsby-ssr.js

import React from 'react'

export const onRenderBody = ({ setPostBodyComponents }) => {
  setPostBodyComponents([
    <script
      key="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
      crossOrigin="anonymous"
      defer
    />
  ])
}

image

All 14 comments

React helmet is a great package for that. You can place it in your page/template or other react components.

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

Sorry if I didn't I make it clear, I mentioned on my original post that I'm running into this exact issue https://github.com/nfl/react-helmet/issues/324 with react-helmet. According to one of the comments, they were also using gatsbyjs and they ended up using exports.onInitialClientRenderer to make it work.

No problem, for that you can put your js file in the static folder and include it like this. See here:
https://www.gatsbyjs.org/docs/static-folder/

<Helmet>
<script src={withPrefix('test.js')} />
</Helmet>

@daydream05 Since the external script you're referring to uses document and since you'd like to execute after render, the best place to put it would be onInitialClientRender in gatsby-browser.js

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

Thanks for being a part of the Gatsby community! 馃挭馃挏

Hey again!

It鈥檚 been 30 days since anything happened on this issue, so our friendly neighborhood robot (that鈥檚 me!) is going to close it.

Please keep in mind that I鈥檓 only a robot, so if I鈥檝e closed this issue in error, I鈥檓 HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

Thanks again for being part of the Gatsby community!

For future visitors: I had a similar problem and what worked for me was to load my (remote) script using a plugin, gatsby-plugin-load-script.

https://www.gatsbyjs.org/packages/gatsby-plugin-load-script/

The instructions on that page are currently just an example Sentry but you only really need to use the src like this:

{ resolve: "gatsby-plugin-load-script", options: { src: "https://url-of-script.min.js", }, },

The above solution works for me - had been trying to get Lottie to load in the browser via CDN once the DOM content had been rendered, and nothing else I tried, including everything in the current Gatsby docs, worked. Thank you @christopherfrance for the tip!

Uncaught TypeError: Cannot read property 'fn' of undefined

Script tags should be placed at the end of page.

Whereas Helmet and gatsby-plugin-load-script try to append script into the head (see link).

Basically, you just need a gatsby-ssr.js file like this, no need plugin at all.

Create gatsby-ssr.js

import React from 'react'

export const onRenderBody = ({ setPostBodyComponents }) => {
  setPostBodyComponents([
    <script
      key="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
      crossOrigin="anonymous"
      defer
    />
  ])
}

image

Uncaught TypeError: Cannot read property 'fn' of undefined

Script tags should be placed at the end of page.

Whereas Helmet and gatsby-plugin-load-script try to append script into the head (see link).

Basically, you just need a gatsby-ssr.js file like this, no need plugin at all.

Create gatsby-ssr.js

import React from 'react'

export const onRenderBody = ({ setPostBodyComponents }) => {
  setPostBodyComponents([
    <script
      key="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
      crossOrigin="anonymous"
      defer
    />
  ])
}

image

What if the same files i want to add gatsby-browser.js ?
i want to add those all files to common.js for avoiding unwanted network call for each file.
THANKS

Uncaught TypeError: Cannot read property 'fn' of undefined

Script tags should be placed at the end of page.

Whereas Helmet and gatsby-plugin-load-script try to append script into the head (see link).

Basically, you just need a gatsby-ssr.js file like this, no need plugin at all.

Create gatsby-ssr.js

import React from 'react'

export const onRenderBody = ({ setPostBodyComponents }) => {
  setPostBodyComponents([
    <script
      key="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
      crossOrigin="anonymous"
      defer
    />
  ])
}

image

Love this answer!
@ReeganExE Just a question, does this mean the script will be loaded on every page transition or it is loaded only once?

Hi, I am a newbie to gatsby. Can anyone help me by proving me an example repository that explains adding multiple external javascript files into a gatsby site and using them?

Thanks in advance.

@SNandini8698 the answer above shows how to pull in external javascript files

I tried gatsby-browser.js and gatsby-ssr.js methods but neither worked well for me.
The solution below with creating a custom hook worked perfectly for me.
https://stackoverflow.com/questions/63193411/using-jquery-and-external-scripts-in-gatsby

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andykais picture andykais  路  3Comments

signalwerk picture signalwerk  路  3Comments

dustinhorton picture dustinhorton  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

kalinchernev picture kalinchernev  路  3Comments