How to add a third party script to a Next.js website

Zach
October 24th, 2021

**EDIT: As of Next 11, I recommend using Next's custom Script Component.

When building out a Next.js website, it is a very common requirement to include a third party <script> to some of the website's pages.

For example, you may need to include a script that supports a chatbot, or scheduling tool, or maybe just a simple widget. Many websites must also embed a third party script to enable an analytics platform like Google Analytics to run across the website.

Whatever the script may be, it's nice to know how to easily add it to your Next.js website, and in this article we'll show you the best way to do it.

Adding the script

Let's assume you need to add this long, ugly <script> to enable a chatbot on one of the pages of your website:

<script type='text/javascript'>
!function(e,t,n,o,a,c)
{
((window.WebConnect = {}),
((a = t.createElement(n)).src =
'https://webchat.goboomtown.com/assets/webConnectChatBox.js'),
(c = t.getElementsByTagName(n)[0]).parentNode.insertBefore(a, c))
}
(window,document,"script"),window.onload=function()
{WebConnect.configOptions({
apiHost: 'https://api.goboomtown.com',
frameSource: 'https://webchat.goboomtown.com',
})}
;
`,
</script>

The best way to add it to a page is by using the <Head> element provided by Next.js.

To use it, import it at the top of your page like so:

import Head from 'next/head';
export default function Page(){
...
}

Next, simply render this <Head> element inside of the page's default component, wrapping it around your <script />.

However, instead of just pasting in the script the way it was given to you, you are going to make use of React's dangerouslySetInnerHTML JSX prop, passing the contents of your <script /> into it's __html object like so:

// pages/some-page.js
import Head from 'next/head';
export default function Page(){
return (
<div>
<Head>
<script
type='text/javascript'
dangerouslySetInnerHTML={{ __html: `
!function(e,t,n,o,a,c)
{
((window.WebConnect = {}),
((a = t.createElement(n)).src =
'https://webchat.goboomtown.com/assets/webConnectChatBox.js'),
(c = t.getElementsByTagName(n)[0]).parentNode.insertBefore(a, c))
}
(window,document,"script"),window.onload=function()
{WebConnect.configOptions({
apiHost: 'https://api.goboomtown.com',
frameSource: 'https://webchat.goboomtown.com',
})}
;
`,
` }}
/>
</Head>
<h1>A page of my website.</h1>
</div>
)
}

Make sure to surround the contents of the script using backticks, as this will allow the code in the string you're passing to be read across multiple indented lines.

And that's pretty much it! When you step back and look, all you've really done is changed the syntax of your <script /> slightly, and placed it inside of Next's <Head /> element.

Another nice thing about this solution is that it works on a page-by-page basis - if you only want the chatbot on a single page (the /help page for example) then you only have to render the <Head /> contaning the script on that page. The script won't be unnecessarily injected into every page of your website, which can be distracting/annoying and effect page performance.

Using _document.js

However, if you do want the script to be loaded into every page of your website, then the best thing to do is to make use of your pages/_document.js page and place Next's <Head> element containing your script in there. This is because the _document.js page is loaded onto every page of your website by default. A common use case for this would be adding a script for Google Analytics into your site, since you most likely want your analytics platform to be running and tracking across every page.

As an example, here is how Google Analytics is being embedded into this very website:

// pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
const GA_TRACKING_ID = 123456;
render() {
return (
<Html>
<Head>
<script
async
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
`,
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;

Just keep in mind that not all third party scripts come with a bunch of messy code to execute between their <script> tags. Some just point to a script using their src attribute, and may make use of other attributes as well, such as this script for a HubSpot chatbot:

<script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/1234567.js"></script>

In this case, you would simply render it as a JSX element inside of the <Head> element like so:

<Head>
<script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/1234567.js" />
<Head/>

But anyway, I think you get the point!

Hopefully this article helped you in understanding the best way to embded a third party script into your Next.js site.

If you found this article helpful, and would like to be notified of new ones, be sure to subscribe to the blog below 😎.

Recommended Posts

HubSpot Forms in React: Submit a form using the HubSpot API

In this post you will learn how to submit HubSpot forms from your React website using the HubSpot API.

Read more

React: Recreating the Hacker News comments section

In this post we'll use React to recreate the Hacker News comment section using a recursively generated comment tree.

Read more