I'm using styled-components with next.js so my styles need to be server-side rendered, hence how can I add google analytics to my website?
I checked next.js google analytics example but as I said my _document file is different because of using styled-components.
// _document.js
import React from 'react'
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () => originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
}
export default MyDocument
But importantly for Google Analytics, JavaScript allows your computer to send and receive messages to other computers connected to the internet. When you visit a site that has implemented Google Analytics, the site will ask your computer to temporarily download some JavaScript instructions from Google Analytics.
Although NextJS is developing rapidly and many features arrive, it still has some cons and issues which you can see below: Cost of flexibility – Next JS does not provide many built-in front pages, so you have to create the whole front-end layer from the ground up.
Big companies like Apple, McDonald's, and Nike trust NextJS, so you should too. NextJS has great adaptability and responsiveness. Websites and web apps created with NextJS work on any device and adapt to any screen size or resolution. Therefore, users can access your website or web app with their favorite device.
Use server-side rendering Using server-side rendering will help your app reduce the time required to render the first page on the client side, so the user will see the content of your page much faster. SSR will also improve application performance, especially on mobile devices.
Next.js since v11 recommends using their <Script>
tag, and the right place to add it is the App
component.
pages/_app.jsx
import React from 'react';
import Script from 'next/script';
const App = ({ Component, pageProps }) => {
return (
<>
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-xxxxxxxxxx"
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){window.dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-xxxxxxxxxx');
`}
</Script>
<Component {...pageProps} />
</>
);
};
export default App;
You can see this solution working in nestjs-starter where I'm also setting the tag from an env var.
This will automatically log pageviews on navigation as well. If this doesn't suit you there's an official example with sending pageview events manually or a thread for doing so with React Router.
For sending custom events you can use window.gtag
. It even has TypeScript support: @types/gtag.js
For v10 and lower use regular <script>
tags according to Google's guide.
I'm using below setup for my personal site (https://github.com/GorvGoyl/Personal-Site-Gourav.io) and it's working fine without any linting errors. Analytics is enabled only for production.
/lib/gtag.ts
file and add your Google Measurement ID:export const GA_TRACKING_ID = "<INSERT_TAG_ID>";
// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
export const pageview = (url: URL): void => {
window.gtag("config", GA_TRACKING_ID, {
page_path: url,
});
};
type GTagEvent = {
action: string;
category: string;
label: string;
value: number;
};
// https://developers.google.com/analytics/devguides/collection/gtagjs/events
export const event = ({ action, category, label, value }: GTagEvent): void => {
window.gtag("event", action, {
event_category: category,
event_label: label,
value,
});
};
types
:npm i -D @types/gtag.js
/pages/_document.tsx
:import Document, { Html, Head, Main, NextScript } from "next/document";
import { GA_TRACKING_ID } from "../lib/gtag";
const isProduction = process.env.NODE_ENV === "production";
export default class MyDocument extends Document {
render(): JSX.Element {
return (
<Html>
<Head>
{/* enable analytics script only for production */}
{isProduction && (
<>
<script
async
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
/>
<script
// eslint-disable-next-line react/no-danger
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>
);
}
}
/pages/_app.tsx
:import { AppProps } from "next/app";
import { useRouter } from "next/router";
import { useEffect } from "react";
import * as gtag from "../lib/gtag";
const isProduction = process.env.NODE_ENV === "production";
const App = ({ Component, pageProps }: AppProps): JSX.Element => {
const router = useRouter();
useEffect(() => {
const handleRouteChange = (url: URL) => {
/* invoke analytics function only for production */
if (isProduction) gtag.pageview(url);
};
router.events.on("routeChangeComplete", handleRouteChange);
return () => {
router.events.off("routeChangeComplete", handleRouteChange);
};
}, [router.events]);
// eslint-disable-next-line react/jsx-props-no-spreading
return <Component {...pageProps} />;
};
export default App;
More info: https://gourav.io/blog/nextjs-cheatsheet
In your _document.js
you override the getInitialProps
method. You can also override the render
method. Simply add
render() {
return (
<Html lang={this.props.lang || "en"}>
<Head>
<script
dangerouslySetInnerHTML={{
__html: `[google analytics tracking code here]`
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
Make sure you import the required components:
import Document, { Html, Head, Main, NextScript } from "next/document"
Do not use the top answer here: using the native <script>
tag is forbidden and it should be defined outside of the <head>
tag.
This is the proper way to include a script tag and configure up Google Analytics in NextJS:
import Script from 'next/script'
import Head from 'next/head'
export default function Index() {
return (
<>
<Head>
<title>Next.js</title>
</Head>
<Script
src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){window.dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
`}
</Script>
</>
)
}
For more info: https://nextjs.org/docs/messages/next-script-for-ga
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With