Using jQuery and external scripts in Gatsby

Viewed 1254

I have a Gatsby website and need to make use of external javascript and jQuery files - stored in the static folder of the project's root.

So far I've tried using React Helmet, Gatsby SSR and Gatsby Browser methods but none of these seem to work. My approaches are outlined below.

Side note: the scripts do load "sometimes" with React Helmet but not always and does not load at all in the production version after running gatsby build.

Using React Helmet

In my layout.js file, I'm using React Helmet to include script references like so:

<Helmet>
    <script src={withPrefix("js/jquery-3.4.1.min.js")}></script>
    <script src={withPrefix("js/plugins.js")}></script>
    <script src={withPrefix("js/common-template.js")}></script>
</Helmet>

As mentioned above, whilst this approach does work sometimes, it doesn't work all the time unless the page is manually refreshed multiple times. And the production version does not work at all.

Using gatsby-ssr

I'm using the following code in gatsby-ssr.js file:

import { withPrefix } from "gatsby"
const React = require("react")

export const onRenderBody = ({ setPostBodyComponents }) => {
  setPostBodyComponents([
    <script key="jquery" src={withPrefix("js/jquery-3.4.1.min.js")} defer />,
    <script key="plugins" src={withPrefix("js/plugins.js")} defer />,
    <script
      key="common-template"
      src={withPrefix("js/common-template.js")}
      defer
    />,
  ])
}

This does not work as well and while checking browser tools, in fetches, it results in The requested resource could not be loaded. However, I can see the file under scripts in web page resources.

Using gatsby-browser

I'm using the following code in gatsby-browser.js file:

const addScript = url => {
  const script = document.createElement("script")
  script.src = url
  script.async = true
  document.body.appendChild(script)
}

export const onClientEntry = () => {
  window.onload = () => {
    addScript("js/jquery-3.4.1.min.js")
    addScript("js/plugins.js")
    addScript("js/common.js")
  }
}

However, this results in the same thing as gatsby-ssr.js method.

Could someone please guide as to what is wrong here and how to fix this? jQuery and the common-template.js file is essential for the website to function and cannot be ignored.

1 Answers

I don't know if it still is your concern but few days ago your words were like mine. I solved that using this react custom hook:

import { useEffect } from 'react';
const useScript = async resourceUrl=> {
  useEffect(() => {
    const script = document.createElement('script');
    script.async = false;
    script.src = resourceUrl;
    document.body.appendChild(script);

return () => {
      document.body.removeChild(script);
    }
  }, [resourceUrl]);
};
export default useScript;

And called it like this:

import useScript from '@/hooks/useScript';
....
import '@/assets/css/styles.css';//not important
import { Helmet } from 'react-helmet';// just an example

const Home: React.FC<PageProps> = () => {
useScript(withPrefix('/js/jquery-3.5.1.min.js'));
useScript(withPrefix('/js/bootstrap.min.js'));
useScript(withPrefix('/js/slick.min.js'));
useScript(withPrefix('/js/latinise_compact.js'));
useScript(withPrefix('/js/scripts.js'));

return (
  <>
    <Helmet>// and so on...

I hope it helps anyone else

Related