How to Add Google Analytics to a Next.js Application (including TypeScript)
How can we add Google Analytics to a Next.js application?
This tutorial assumes that we have a Google Analytics project created for our Next.js project with a Measurement ID.
1. Create a Google Analytics environment variable
First, let’s create an environment variable for our Google Analytics Measurement ID.
NEXT_PUBLIC_GA_ID=G-FSC4AH1C9X
Locally, this should reside in a .env.local
or .env
file.
Remember to set this environment variable wherever this application is deployed in production.
2. Inject Google Analytics script in _document.js
Next, we’ll want to inject the Google Analytics Global Site Tag (gtag.js
) into our site’s <head>
.
To access the Next.js <Head>
tag, we’ll need a Next.js custom document called /pages/_document.js
.
Here, we’ll inject the Google Analytics script into /pages/_document.js
.
import Document, { Html, Head, Main, NextScript } from 'next/document';
const gtag = `https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_ID}`;
export default class MyDocument extends Document {
render() {
return (
<Html>
<Head>
<script async src={gtag} />
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${process.env.NEXT_PUBLIC_GA_ID}', {
page_path: window.location.pathname,
});
`
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
3. Track page views in _app.js
In order to track page views in our application, we’ll want to add a simple useEffect()
hook into our _app.js
that listens for routeChangeComplete
events.
import { useEffect } from 'react';
import { useRouter } from 'next/router';
function MyApp({ Component, pageProps }) {
const router = useRouter();
useEffect(() => {
const handleRouteChange = url => {
window.gtag('config', process.env.NEXT_PUBLIC_GA_ID, {
page_path: url,
});
}
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
}
}, [router.events]);
return <Component {...pageProps} />
}
export default MyApp
4. Optional: only track in production
If we want to limit analytics to our production environment, we can check process.env.NODE_ENV
.
Modify _document.js
In /pages/_document.js
, let’s declare a boolean variable to check for production (can be outside the component).
const isProd = process.env.NODE_ENV === "production";
Then, we can wrap everything in <Head>
in a conditional.
<Head>
{isProd && (
<>
{/* The two script tags */}
</>
)}
</Head>
Modify _app.js
In /pages/_app.js
, let’s declare the same boolean variable for production.
const isProd = process.env.NODE_ENV === "production";
Then, we can modify handleRouteChange
to only fire in production.
const handleRouteChange = url => {
if (isProd) {
window.gtag('config', process.env.NEXT_PUBLIC_GA_ID, {
page_path: url,
});
}
};
Add Google Analytics to TypeScript Next.js
If we want to add Google Analytics to a TypeScript application, we’ll need to add a few types.
First, we’ll need to install the types library for gtag.js
.
npm i -D @types/gtag.js
In /pages/_document.tsx
, we’ll want to type the return object.
// ...
export default class MyDocument extends Document {
render(): JSX.Element {
// ...
}
}
Similarly, in /pages/_app.tsx
, we’ll want type the parameters
const App = ({ Component, pageProps }: AppProps): JSX.Element => {
// ...
const handleRouteChange = (url: URL) => {
// ...
}
// ...
};