Enea Xharja Logo

How to add custom JavaScript to a Gatsby site

While working on a side project recently, I found myself in the need to add some custom JavaScript to a Gatsby site. Gatsby doesn't use an index.html file. Instead, it uses an html.js file, which is hidden by default.

If you need to add an external script (or 3rd party script) in your Gatsby website, without using any plugin, the best approach would be to use Gatsby SSR API.

However, some APIs might not be available in gatsby-ssr.js. In that case, you will need to customize your site’s html.js file.

First, you need to copy the default one into your source tree by running:

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

Your default html.js will look like this:

js
1import React from 'react';
2import PropTypes from 'prop-types';
3
4export default function HTML(props) {
5 return (
6 <html {...props.htmlAttributes}>
7 <head>
8 <meta charSet="utf-8" />
9 <meta httpEquiv="x-ua-compatible" content="ie=edge" />
10 <meta
11 name="viewport"
12 content="width=device-width, initial-scale=1, shrink-to-fit=no"
13 />
14 {props.headComponents}
15 </head>
16 <body {...props.bodyAttributes}>
17 {props.preBodyComponents}
18 <div
19 key={`body`}
20 id="___gatsby"
21 dangerouslySetInnerHTML={{ __html: props.body }}
22 />
23 {props.postBodyComponents}
24 </body>
25 </html>
26 );
27}
28
29HTML.propTypes = {
30 htmlAttributes: PropTypes.object,
31 headComponents: PropTypes.array,
32 bodyAttributes: PropTypes.object,
33 preBodyComponents: PropTypes.array,
34 body: PropTypes.string,
35 postBodyComponents: PropTypes.array,
36};

Now, just before the closing </body> tag, you can add the external script or even some custom JavaScript:

js
1import React from 'react';
2import PropTypes from 'prop-types';
3
4export default function HTML(props) {
5 return (
6 <html {...props.htmlAttributes}>
7 <head>
8 <meta charSet="utf-8" />
9 <meta httpEquiv="x-ua-compatible" content="ie=edge" />
10 <meta
11 name="viewport"
12 content="width=device-width, initial-scale=1, shrink-to-fit=no"
13 />
14 {props.headComponents}
15 </head>
16 <body {...props.bodyAttributes}>
17 {props.preBodyComponents}
18 <div
19 key={`body`}
20 id="___gatsby"
21 dangerouslySetInnerHTML={{ __html: props.body }}
22 />
23 {props.postBodyComponents}
24 {/* External Script */}
25 <script
26 src="https://cdnjs.cloudflare.com/some-cookie-or-other-tracker.js"
27 type="text/javascript"
28 aysnc
29 />
30 {/* Custom JavaScript */}
31 <script
32 dangerouslySetInnerHTML={{
33 __html: `
34 var name = 'world';
35 console.log('Hello ' + name);
36 `,
37 }}
38 />
39 </body>
40 </html>
41 );
42}
43
44HTML.propTypes = {
45 htmlAttributes: PropTypes.object,
46 headComponents: PropTypes.array,
47 bodyAttributes: PropTypes.object,
48 preBodyComponents: PropTypes.array,
49 body: PropTypes.string,
50 postBodyComponents: PropTypes.array,
51};

If you want to learn more about Gatsby and its ecosystem, head over to the official website.