There are lots of tutorials online that give you instructions on how to set up Google Analytics with Next.js project.
But most of them require you to use react-ga
, a library that basically wraps Google Analytics logic inside a React component.
This is good, but I personally prefer a solution that:
react-ga
in this case)My solution is based on an official example of Next.js team here: Example app with analytics
You can also check this Github issue for some of the other workarounds that people used: Adding GA script tag? #160
Let’s get started!
This helper file stores your Google Analytics tracking ID and provides some methods that you need to track your page views.
Add this to lib/gtag.js
:
export const GA_TRACKING_ID = 'UA-XXXXXXXXX-X' // This is your GA Tracking ID
// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
export const pageview = (url) => {
window.gtag('config', GA_TRACKING_ID, {
page_path: url,
})
}
// https://developers.google.com/analytics/devguides/collection/gtagjs/events
export const event = ({ action, category, label, value }) => {
window.gtag('event', action, {
event_category: category,
event_label: label,
value: value,
})
}
Create a custom _document.js
that will load our Google Analytics script for us. We will only load this script in production so that we don’t track items locally. In the pages directory create a new file, _document.js
and add the following code:
File: pages/_document.js
import { Fragment } from 'react'
import Document, { Head, Main, NextScript } from 'next/document'
import FavIcon from '../assets/image/favicon.png'
import { GA_TRACKING_ID } from '../lib/gtag'
export default class CustomDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
const initialProps = await Document.getInitialProps(ctx)
// Check if in production
const isProduction = process.env.NODE_ENV === 'production'
return {
...initialProps,
isProduction,
}
}
render() {
const { isProduction } = this.props
return (
<html lang="en">
<Head>
<link rel="shortcut icon" type="image/x-icon" href={FavIcon} />
{/* We only want to add the scripts if in production */}
{isProduction && (
<Fragment>
{/* Global Site Tag (gtag.js) - Google Analytics */}
<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,
});
`,
}}
/>
</Fragment>
)}
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
You will trigger pageview event here when the router detects route is changed.
File: pages/_app.js
import React, { Fragment } from 'react'
import Router from 'next/router'
import * as gtag from 'common/src/lib/gtag'
// Notice how we track pageview when route is changed
Router.events.on('routeChangeComplete', (url) => gtag.pageview(url))
export default ({ Component, pageProps }) => {
return (
<Fragment>
<Component {...pageProps} />
</Fragment>
)
}
Now you can see how easy it is to make Google Analytics works with Next.js without any external dependency.
Happy coding!