How to add 3rd party script in your gatsby website

May 06, 2020 Amrish Kushwaha...
twitterlinkedinreddit
How to add 3rd party script in your gatsby website

Gatsby is a great choice especially when you want to build static websites such as marketing websites, portfolios, etc.

Tracking your website:

One of the main purposes of the website is to know is the behavior of visitors on websites. Either you do use google analytics tracking or marketing CRMs such as HubSpot, agile CRM, etc. or other services who want to provide you info and behavior on the website.

In order to do so, these services give you some tracking code or external scripts to put it on your website so that they can track your website and give it to relevant results you asked for.

There are a number of ways to solve this problem for Gatsby Website and a couple of solutions are as follows

  1. Use Google Tag Manager to manage your tags or tracking codes ( here you have to at least add GTM plugin in your gatsby website )

  2. Use already build-in plugins that gatsby or community provides, check this out - https://www.gatsbyjs.org/plugins/

  3. If you do not want to use GTM or if you didn't find any relevant plugins for your use case in gatsby, then you can also add your external script { tracking code } through a bit coding in your gatsby website which is very easy.

Adding external scripts in gatsby website

Here I will discuss how to add external scripts { without any plugin }

There are two ways you can do it

  • Using Gatsby SSR API or
  • Modifying html.js

Gatsby SSR API:

Gatsby provides many SSR APIs and one of them is onRenderBody API. This API is useful when you want to set some custom head and body components in your html.js which is responsible to create HTML structure of pages of the gatsby website.

onRenderBody API takes two parameters - apiCallbackContext & pluginOptions and returns undefined.

apiCallbackContext

⇒ this is an object which contains several keys such as

  • pathname: string
  • setHeadComponents: function
  • setHtmlAttributes: function
  • setBodyAttributes: function
  • setPreBodyComponents: function
  • setPostBodyComponents: function
  • setBodyProps: function

pluginOptions

⇒ It is another parameter passed to onRenderBody API. It is mostly used when you are creating your own gatsby plugins using this SSR API.

For more info, refer to gatsby docs here - https://www.gatsbyjs.org/docs/ssr-apis/#onRenderBody

In order to add scripts, these three functions are useful for you - setHeadComponents, setPreBodyComponents and setPostBodyComponents.

setHeadComponents - when you want to add the script in the head tag.

setPreBodyComponents - when you want to add a script just after opening the tag of the body.

setPostBodyComponents - when you want to add the script just before the closing tag of the body.

InputType of all the above three components is the array. So if you want to add something there, you have to add it in array type.

Let's try an example to understand it more ⇒

Let's say we want to add these external scripts on the head, just for example

<script src="https://cdnjs.cloudflare.com/ajax/libs/tracking.js/1.1.3/tracking-min.js" async></script> // Choose

and this script in just before closing body tag.


<script src="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/alertify.js" async></script>
<script type="text/javascript">
	console.log('Happy Coding and Stay Safe!!');
</script>

So here are steps to add these scripts:

  1. First, open gatsby.ssr.js file in the root of your project

  2. Implement code in setHeadComponents as follows

setHeadComponents([
   <script key="tracking" src="https://cdnjs.cloudflare.com/ajax/libs/tracking.js/1.1.3/tracking-min.js" type="text/javascript" async />
]);
  1. Implement code in setPostBodyComponents as follows
setPostBodyComponents([
    <script
			key="alertify"
      src="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/alertify.js"
      type="text/javascript"
      aysnc
    />,
    <script
      key="fun_javascript"
      dangerouslySetInnerHTML={{
        __html: `
        console.log('Happy Coding and Stay Safe!!')
      `,
      }}
    />,
  ])

overall gatsby.ssr.js will look like this

import React from "react"
export const onRenderBody = (
  { setHeadComponents, setPostBodyComponents },
  pluginOptions
) => {
  setHeadComponents([
    <script
			key="tracking"
      src="https://cdnjs.cloudflare.com/ajax/libs/tracking.js/1.1.3/tracking-min.js"
      type="text/javascript"
      async
    />,
  ])
  setPostBodyComponents([
    <script
			key="alertify"
      src="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/alertify.js"
      type="text/javascript"
      aysnc
    />,
    <script
      key="fun_javascript"
      dangerouslySetInnerHTML={{
        __html: `
        console.log('Happy Coding and Stay Safe!!')
      `,
      }}
    />,
  ])
}

that's it.

Modifying html.js

Another way to add scripts is directly modifying html.js. you should preferably use SSR API. I will suggest that use this method when you have not other options.

If you need to customize your site's html.js, copy the default one into your source tree by running:

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

And then make modifications as needed in html.js.

Initially html.js looks like this ⇒

import React from "react"
import PropTypes from "prop-types"

export default function HTML(props) {
  return (
    <html {...props.htmlAttributes}>
      <head>
        <meta charSet="utf-8" />
        <meta httpEquiv="x-ua-compatible" content="ie=edge" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no"
        />
        {props.headComponents}
      </head>
      <body {...props.bodyAttributes}>
        {props.preBodyComponents}
        <div
          key={`body`}
          id="___gatsby"
          dangerouslySetInnerHTML={{ __html: props.body }}
        />
        {props.postBodyComponents}
      </body>
    </html>
  )
}

HTML.propTypes = {
  htmlAttributes: PropTypes.object,
  headComponents: PropTypes.array,
  bodyAttributes: PropTypes.object,
  preBodyComponents: PropTypes.array,
  body: PropTypes.string,
  postBodyComponents: PropTypes.array,
}

So If we take that example from the SSR API section and want to implement them using this method. It is very easy. You just have to paste relevant scripts at the right locations. In our case, it is this

import React from "react"
import PropTypes from "prop-types"

export default function HTML(props) {
  return (
    <html {...props.htmlAttributes}>
      <head>
        <meta charSet="utf-8" />
        <meta httpEquiv="x-ua-compatible" content="ie=edge" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no"
        />
        {props.headComponents}
        <script
          key="tracking"
          src="https://cdnjs.cloudflare.com/ajax/libs/tracking.js/1.1.3/tracking-min.js"
          type="text/javascript"
          async
        />
      </head>
      <body {...props.bodyAttributes}>
        {props.preBodyComponents}
        <div
          key={`body`}
          id="___gatsby"
          dangerouslySetInnerHTML={{ __html: props.body }}
        />
        {props.postBodyComponents}
        <script
          key="alertify"
          src="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/alertify.js"
          type="text/javascript"
          aysnc
        />
        <script
          key="fun_javascript"
          dangerouslySetInnerHTML={{
            __html: `
        console.log('Happy Coding and Stay Safe!!')
      `,
          }}
        />
      </body>
    </html>
  )
}

HTML.propTypes = {
  htmlAttributes: PropTypes.object,
  headComponents: PropTypes.array,
  bodyAttributes: PropTypes.object,
  preBodyComponents: PropTypes.array,
  body: PropTypes.string,
  postBodyComponents: PropTypes.array,
}

That's it.

Now you can deploy your website with a huge smile.

Happy Coding and Be Safe.