Búsqueda de sitios web

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.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;

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.ts y 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 types de 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.jsx
import 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.jsx
import 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>
  )
}

Artículos relacionados