formerly I was using react-ga npm module to insert google analytics in my next js app. and It was simply like this:
import ReactGA from \'react-ga\'
export cons
Since you are using nextJS, there is no need to add pure javascript from Google Analytics, all you need to have is the GA tracking id.
Then you create util function:
export const event = ({ action, category, label, value }) => {
window.gtag('event', action, {
event_category: category,
event_label: label,
value: value
})
}
and add this in your _document.js:
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}');
`}}
/>
After that, you just need to import the util function in your page/ components and call:
gtag.event({
action: 'submit_form',
category: 'Contact',
label: this.state.message
})
Reference: example of NextJS with GA
In order to use Google Tag Manager you should inject your tag manager script on every page. since _document.js
is the wrapper for every page, you should add the GTM script to _document.js
in the head section like this:
<Head>
<script dangerouslySetInnerHTML={{
__html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-*****');`,
}}>
</script>
...
</Head>
Now you are all set to use Google Tag Manager in your next-js app. You should only proceed to handle pageview and other analytics related stuff from your GTM dashboard.
To set up google analytics pageview for single page applications(like nextjs) you can follow these steps.
I'm using redux in my next.js application.
And this is pretty good solution if you're using redux: redux-beacon + react-gtm-module.
here is initialization code. This code can be triggered with hooks or componentDidMount in _app.js or with redux action if you're using redux.
const dataLayer = { ...your dataLayer config... }
const tagManagerArgs = {
gtmId: process.env.GTM_ID,
auth: process.env.GTM_AUTH,
preview: process.env.GTM_PREVIEW,
dataLayer
}
TagManager.initialize(tagManagerArgs)
below is middleware created with eventMap.
import { EventsMapper, createMiddleware } from 'redux-beacon'
import GoogleTagManager from '@redux-beacon/google-tag-manager'
const gtm = GoogleTagManager()
export const eventsMap: EventsMapper = action => {
switch (action.type) {
default:
return []
}
}
export const gtmMiddleware = createMiddleware(eventsMap, gtm)
Im using react-gtm-module and config in _app.js
inside componentDidMount
componentDidMount() {
const tagManagerArgs = {
gtmId = 'GTM-00001'
}
TagManager.initialize(tagManagerArgs);
}
this is my solution updated at Feb 11, 2020
I found a better way of implementing it. We can use react-gtm-module
library for it.
As Ryan Elainska mentions in their blog, Google Tag Manager in Next.js in the _app.js
file of my NextJS installation:
import App, { Container } from 'next/app'
import React from 'react'
import './app.css'
import TagManager from 'react-gtm'
const tagManagerArgs = {
id: 'GTM-XXXXXXX'
}
class MyApp extends App {
componentDidMount () {
TagManager.initialize(tagManagerArgs)
}
render () {
const { Component, pageProps } = this.props
return (
<Container>
<Component {...pageProps} />
</Container>
)
}
}
export default MyApp
There is no need for any special library and some answers here look uncomplete. Just add the script to <Head>
and noscript to <body>
in _document.js
import Head from 'next/document'
<Head>
<script dangerouslySetInnerHTML={{__html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');`}} />
</Head>
<body style={{ margin: 0 }}>
<noscript dangerouslySetInnerHTML={{ __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
}}
/>
<Main />
<NextScript />
</body>