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>
)
8
Answers
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:
Create a folder
static
to the root of your project.Put your script
script.js
in the folderstatic
.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:
Notice the imports
and the script element.
This would have saved hours of my time, hopefully this does it for someone else.
React works with dynamic DOM. But for rendering it by browser, your web server should send a static index page, where React will be included as another
script
tag.So, take a look on your
index.html
page, which you can find inpublic
folder. There you could insert yourscript
tag in the header section, for example.Gatsby uses html.js in the src folder. Not index.html like most react projects.
Example html.js file:
For adding custom Javascript using
dangerouslySetInnerHTML
insidesrc/html.js
:You can try adding your js there but, note that your js may not work as expected. You can always look into react-helmet for more dynamic apps and adding scripts to
<head>
.Gatsby Documentation: https://www.gatsbyjs.org/docs/custom-html/
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
userequire()
to execute the script insideuseEffect()
like this:To run it on client-side, you could check the
window
object inside yourscript.js
file if you didn’t run it in useEffect: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.html.js
file:If you’d like to use a Gatsby plugin, which to me is no different from using an external library like Helmet (plugins are npm packages after all), you could use gatsby-plugin-load-script.
You can provide either the url to the
src
attribute or a local path. If you’re going to store your JS in a local file such assome-minified-js.min.js
– make sure to store in thestatic
directory at the root of your project.Once you do this, you can access via the global object:
For example, I was trying to include a very small JS library via a minified file, so I stored the file in
/static/my-minified-library.min.js
and then:npm i --save gatsby-plugin-load-script
gatsby-config.js
You can do this very easily with the Gatsby plugin "gatsby-plugin-load-script."
Simply do this:
static
at the root of your gatsby appgatsby-config.js
Just create
gatsby-ssr.js
file on root folderand add the following pattern for your scripts folder
Then, you at the end of dom you’ll see the links to scripts
I’m not sure if anyone still needs this answer, but here it goes:
The answer by Elliot Marques is excellent. If you need it for a local file, upload the script to Github and use a service like JSDelivr. It saves a lot of time and stress.