How to include local javascript on a Gatsby page?

I'm a total React newbie and I guess there is something fundamental I don't quite understand here. A default Gatsby page looks like this. Is there a way to use a local .js file somewhat like this?

<script src="../script/script.js"></script>

What I would like to achieve is to have react ignore script.js but still have the client side use it. A default Gatsby page looks like this, is it possible to do somerthing like that there?

import React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

const IndexPage = () => (
  <Layout>
    <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
    <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
      <Image />
    </div>
    <Link to="/page-2/">Go to page 2</Link>
  </Layout>
)

After several hours of frustration I finally stumbled upon discussion on GitHub that solved this for me. In Gatsby, there is a thing called static folder, for which one use case is including a small script outside of the bundled code.

Anyone else in the same situation, try proceeding as follows:

  1. Create a folder static to the root of your project.

  2. Put your script script.js in the folder static.

  3. Include the script in your react dom with react-helmet.

So in the case of the code I posted in my original question, for instance:

import React from "react"
import Helmet from "react-helmet"
import { withPrefix, Link } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

const IndexPage = () => (
  <Layout>
    <Helmet>
        <script src={withPrefix('script.js')} type="text/javascript" />
    </Helmet>
    <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
    <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
      <Image />
    </div>
    <Link to="/page-2/">Go to page 2</Link>
  </Layout>
)

Notice the imports

import Helmet from "react-helmet"
import { withPrefix, Link } from "gatsby"

and the script element.

<Helmet>
    <script src={withPrefix('script.js')} type="text/javascript" />
</Helmet>

This would have saved hours of my time, hopefully this does it for someone else.


Just create gatsby-ssr.js file on root folder

and add the following pattern for your scripts folder

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
    />
  ])
}

Then, you at the end of dom you'll see the links to scripts enter image description here


There are many ways to add scripts in GatsbyJS...

To execute a script on a specific page

  • create a stateless scriptComponent.js file and place it inside your /src folder.

  • in your scriptComponent.js use require() to execute the script inside useEffect() like this:

     useEffect(() => {
       // This runs the script
       const myScript = require('../script.js')
     }, [])
    
     return <div />
    
  • To run it on client-side, you could check the window object inside your script.js file:

     if(typeof window !== 'undefined' && window.document) {
        // Your script here...
     }
    
  • finally, go to the page you want to execute the script in it (e.g. /pages/myPage.js ), and add the component <scriptComponent />

If you want to execute a script globally in (every component/page) you could use the html.js file.

  • first, you'll have to extract the file (in case you didn't) by running:

cp .cache/default-html.js src/html.js

  • inside your html.js file:
<script dangerouslySetInnerHTML= {{ __html:`
  // your script here...
`}} />