javascript - ¿Cómo usar Google Analytics con una aplicación de Next.js?
Estoy usando styled-components con next.js, así que mis estilos necesitan ser renderizados del lado del servidor, entonces ¿cómo puedo agregar Google Analytics a mi sitio web?
Revisé el ejemplo de Next.js con Google Analytics, pero como dije, mi archivo _document es diferente debido al uso de 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
Respuesta #1
Next.js desde la versión 11 recomienda usar su etiqueta <Script>, y el lugar correcto para agregarla es el componente App.
pages/_app.jsximport 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;
Puedes ver esta solución funcionando en nestjs-starter donde también estoy configurando la etiqueta desde una variable de entorno.
Para v10 y versiones anteriores, use etiquetas regulares <script> según la guía de Google.
Ten en cuenta que Google Analytics realiza un seguimiento automático de las páginas, pero esto no funcionará para todos los casos de uso. Por ejemplo, los cambios en los parámetros hash y search no se rastrean. Esto puede generar mucha confusión. Por ejemplo, al usar HashRouter o enlaces de anclaje, la navegación no se rastreará. Para tener control total sobre el seguimiento de vistas de página, puedes desactivar el seguimiento automático. Consulta para una explicación detallada: La Guía Definitiva de Google Analytics (UA y GA4) en React (O En Cualquier Otra Cosa)
Seguimiento de páginas del manual: https://stackoverflow.com/a/63249329/2771889
Respuesta #2
Configurar Google Analytics con NextJS usando Typescript
Estoy usando la siguiente configuración para mi sitio personal (https://github.com/GorvGoyl/Personal-Site-Gourav.io) y está funcionando bien sin ningún error de linting. La analítica solo está habilitada para producción.
- Crea un proyecto de Google Analytics y obtén el ID de medición.
- En tu proyecto NextJS, crea el archivo
/lib/gtag.tsy añade tu ID de medición de Google:
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,
});
};
- También instala los
typesde gtag:
npm i -D @types/gtag.js
- Crea
/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>
);
}
}
- Crea
/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;
Más información: https://gourav.io/blog/nextjs-cheatsheet
Respuesta #3
En tu _document.js sobrescribes el método getInitialProps. También puedes sobrescribir el método render. Simplemente agrega
render() {
return (
<Html lang={this.props.lang || "en"}>
<Head>
<script
dangerouslySetInnerHTML={{
__html: `[google analytics tracking code here]`
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
Asegúrate de importar los componentes requeridos:
import Document, { Html, Head, Main, NextScript } from "next/document"Respuesta #4
No uses la respuesta principal aquí: usar la etiqueta nativa <script> está prohibido y debería definirse fuera de la etiqueta <head>.
Esta es la manera adecuada de incluir una etiqueta de script y configurar Google Analytics en 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>
</>
)
}
Para más información: https://nextjs.org/docs/messages/next-script-for-ga
Respuesta #5
Este es el método recomendado por next.js.
/components/GoogleAnalytics.jsximport Script from 'next/script'
import { useEffect } from 'react'
import { useRouter } from 'next/router'
const GA_TRACKING_ID = '...'
export default () => {
const router = useRouter()
useEffect(() => {
const handleRouteChange = url => {
window.gtag('config', GA_TRACKING_ID, { page_path: url })
}
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
return (
<>
<Script
strategy='afterInteractive'
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
/>
<Script
id='gtag-init'
strategy='afterInteractive'
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,
});
`
}}
/>
</>
)
}
/pages/_app.jsximport GoogleAnalytics from './../components/GoogleAnalytics'
export default function App ({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
{
process.env.NODE_ENV === 'production' &&
<GoogleAnalytics />
}
</>
)
}
Respuesta #6
Next.js 14+
Para Next.js 14+ es bastante sencillo: puedes usar el paquete @next/third-parties/google para configurar Google Analytics solo o a través de Google Tag Manager (GTM).
Para el directorio app:
Para cargar análisis para todas las rutas, incluye el componente en el diseño raíz:
import { GoogleAnalytics } from '@next/third-parties/google'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
<GoogleAnalytics gaId="G-XYZ" />
</html>
)
}
Para cargar análisis para una sola ruta, incluye el componente en tu archivo de página:
import { GoogleAnalytics } from '@next/third-parties/google'
export default function Page() {
return <GoogleAnalytics gaId="G-XYZ" />
}
Para el directorio pages:
Para cargar análisis para todas las rutas, incluya el componente en el archivo _app:
import { GoogleAnalytics } from '@next/third-parties/google'
export default function MyApp({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<GoogleAnalytics gaId="G-XYZ" />
</>
)
}
Para cargar análisis para una sola ruta, incluye el componente en tu archivo de página:
import { GoogleAnalytics } from '@next/third-parties/google'
export default function Page() {
return <GoogleAnalytics gaId="G-XYZ" />
}
Para enviar eventos personalizados
Puedes usar cualquiera de sendGAEvent (si está configurado a través de <GoogleAnalytics />):
import { sendGAEvent } from '@next/third-parties/google'
export function EventButton() {
return (
<div>
<button
onClick={() => sendGAEvent('event', 'buttonClicked', { value: 'xyz' })}
>
Send Event
</button>
</div>
)
}
O a través de sendGTMEvent (si está configurado a través de <GoogleTagManager />):
import { sendGTMEvent } from '@next/third-parties/google'
export function EventButton() {
return (
<div>
<button
onClick={() => sendGTMEvent({ event: 'buttonClicked', value: 'xyz' })}
>
Send Event
</button>
</div>
)
}
