DEV Community

Cover image for Cómo integrar Google Analytics en NextJS para cumplir con la Ley de Protección de Datos
Dubis
Dubis

Posted on • Originally published at dubis.dev

Cómo integrar Google Analytics en NextJS para cumplir con la Ley de Protección de Datos

¿Qué vamos a hacer?

En este post configuraremos Google Analytics en una página web creada con NextJS, teniendo en cuenta la autorización del usuario para la recogida de datos y el uso de cookies.


Requisitos previos

Antes de comenzar con el código, necesitarás tener acceso a los siguientes recursos:

Puedes consultar la documentación oficial para saber qué son y cómo configurarlos en tu proyecto.

También deberás tener acceso a una cuenta de Google analytics y deberás crear un nuevo proyecto de GA y obtener la ID de seguimiento.


Configurar Google Analytics en la web

Configurando los scripts de Google Analytics

Lo primero que deberemos hacer es configurar los scripts de GA en el archivo _document.js. Estos scripts son los que se encargan de configurar la instancia de GA a nivel global en nuestro sitio web. Para ello abrimos el archivo _document.js y añadimos las siguientes líneas de código en el elemento head:

<script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GOOGLE_ANALYTICS}`} />
<script dangerouslySetInnerHTML={{
    __html:`
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}

        gtag('consent', 'update', {
            'analytics_storage': 'granted'
        });

        gtag('js', new Date());

        gtag('config', '${process.env.GOOGLE_ANALYTICS}', {
            page_path: window.location.pathname,
        });
        `,
        }} />

Enter fullscreen mode Exit fullscreen mode

El archivo final debería quedar similar a esto:

import Document, { Html, Head, Main, NextScript } from "next/document";

class MyDocument extends Document {
    static async getInitialProps(ctx) {
        const initialProps = await Document.getInitialProps(ctx);
        return { ...initialProps };
    }

    render() {
        return (
            <Html>
                <Head>
                    <script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GOOGLE_ANALYTICS}`} />
                    <script
                        dangerouslySetInnerHTML={{
                            __html:`
                            window.dataLayer = window.dataLayer || [];
                            function gtag(){dataLayer.push(arguments);}

                            gtag('consent', 'update', {
                                'analytics_storage': 'granted'
                            });

                            gtag('js', new Date());

                            gtag('config', '${process.env.GOOGLE_ANALYTICS}', {
                                page_path: window.location.pathname,
                            });
                            `,
                        }}
                    />
                </Head>
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        );
    }
}

export default MyDocument;
Enter fullscreen mode Exit fullscreen mode

Como ves, estamos utilizando una variable de entorno, que configuraremos más adelante, donde se almacenará el ID de seguimiento de Google Analytics.

Además, para poder detectar los diferentes eventos que ocurren en la página, es necesario añadir las siguientes líneas al archivo _app.js:

import { useEffect } from "react";
import { useRouter } from "next/router";

//dentro del componente App
const router = useRouter();

useEffect(() => {
    const handleRouteChange = (url) => {
        window.gtag("config", process.env.GOOGLE_ANALYTICS, {
            page_path: url,
        });
    };
    router.events.on("routeChangeComplete", handleRouteChange);
    return () => {
        router.events.off("routeChangeComplete", handleRouteChange);
    };
}, [router.events]);
Enter fullscreen mode Exit fullscreen mode

El archivo final quedará similar a esto:

import "../styles/globals.css";
import { useEffect } from "react";
import { useRouter } from "next/router";

function App({ Component, pageProps }) {
    const router = useRouter();

    useEffect(() => {
        const handleRouteChange = (url) => {
            window.gtag("config", process.env.GOOGLE_ANALYTICS, {
                page_path: url,
            });
        };
        router.events.on("routeChangeComplete", handleRouteChange);
        return () => {
            router.events.off("routeChangeComplete", handleRouteChange);
        };
    }, [router.events]);

    return <Component {...pageProps} />

}

export default App;

Enter fullscreen mode Exit fullscreen mode

Pidiendo permiso al usuario: renderizado condicional de los scripts de GA.

Con esto ya tenemos Google Analytics funcionando en nuestro sitio web. Pero ahora debemos tener en cuenta que Google Analtics solo debe ser utilizado tras el consentimineto del usuario, por lo que procederemos a añadir los elementos necesarios para pedir ese permiso.

El primer cambio que debemos realizar es configurar los scripts de analytics para que no se carguen automáticamente. Para ello volveremos al archivo _document.js y añadiremos un condicional a nuestro código:

<script
    dangerouslySetInnerHTML={{
        __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}

            //configuramos el permiso como denegado en primera instancia
            gtag('consent', 'default', {
                'analytics_storage': 'denied'
            });

            gtag('js', new Date());

            //comprobamos el consentimiento
            if( consentimiento ) {
                gtag('consent', 'update', {
                'analytics_storage': 'granted'
                });
            }

            gtag('config', '${process.env.GOOGLE_ANALYTICS}', {
                page_path: window.location.pathname,
            });
        `,
    }}
/>
Enter fullscreen mode Exit fullscreen mode

Ahora no se cargan automáticamente los scripts sino que dependerá del consentimiento del usuario.

Es el momento de preguntar al usuario si desea o no que realicemos seguimiento de sus datos. Para ello, podemos utilizar algún componente de React ya existente que nos permita preguntar al usuario y almacenar sus preferencias en una cookie de preferencias.

En este caso utilizaremos la librería react-cookie-consent.

Podemos isntalarla a través de la consola en nuestro proyecto:

npm install react-cookie-consent

# o utilizando yarn

yarn add react-cookie-consent
Enter fullscreen mode Exit fullscreen mode

Una vez instalado debemos añadir el componente de forma global, de manera que entre donde entre el usuario, se le pregunte por sus preferencias en caso de no tener un registro previo de las mismas. Este componente se encarga automáticamente de comprobar si ya hay una cookie previa de preferencias por lo que será muy facil implementar el sistema.

Para añadirlo de forma global lo añadimos al componente App de nuestra web:

import "../styles/globals.css";
import { useEffect } from "react";
import { useRouter } from "next/router";
import CookieConsent from "react-cookie-consent";

function App({ Component, pageProps }) {
const router = useRouter();

    useEffect(() => {
        const handleRouteChange = (url) => {
            window.gtag("config", process.env.GOOGLE_ANALYTICS, {
                page_path: url,
            });
        };
        router.events.on("routeChangeComplete", handleRouteChange);
        return () => {
            router.events.off("routeChangeComplete", handleRouteChange);
        };
    }, [router.events]);

    return (
        <>
            <Component {...pageProps} />
            <CookieConsent
            location="bottom"
            buttonText="Sí, utilizar cookies."
            onAccept={() => location.reload()}
            cookieName="CookieConsent"
            expires={150}
            enableDeclineButton="true"
            declineButtonText="No, no utilizar cookies"
            >
            Poner aquí el mensaje sobre el uso de cookies
            <a href="#enlace_hacia_politica_de_cookies">Política de Cookies</a>.
        </CookieConsent>
        </>
    );

}

export default App;

Enter fullscreen mode Exit fullscreen mode

Puedes cosultar el repo del componente para configurar a tu gusto este componente.

Ya tenemos la capacidad de crear una cookie de preferencias y de preguntarle al usuario qué es lo que quiere. Ahora debemos volver al archivo _document.js e introducir la función que nos devuelva el valor de la cookie de preferencias, para saber si debemos o no, cargar el script de rastreo.

Añadimos lo siguiente en el archivo _document.js:

<script
    dangerouslySetInnerHTML={{
        __html: `
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        //this defaults to denying
        gtag('consent', 'default', {
            'analytics_storage': 'denied'
        });

        gtag('js', new Date());

        //este función es la que nos devuelve el valor de la cookie de preferencias
        function getCookie() {
            const value = "; " + document.cookie;
            const parts = value.split("; CookieConsent=");
            if (parts.length === 2) return parts.pop().split(';').shift();
        }

        //únicamente si el valor es true, se cargan los scripts de Google Analytics.
        if(getCookie() === "true"){
            gtag('consent', 'update', {
                'analytics_storage': 'granted'
            });
        }

        gtag('config', '${process.env.GOOGLE_ANALYTICS}', {
            page_path: window.location.pathname,
        });
        `,
    }}
/>
Enter fullscreen mode Exit fullscreen mode

Con esto ya tendremos todo funcionando 🚀. Ahora deberás hacer un deploy en Vercel y configurar la variable de entorno GOOGLE_ANALYTICS con el valor del ID de rastreo de tu ditio web.
Tras añadir la variable de entorno deberás de hacer otro deploy para que estas san tenidas en cuenta en tu sitio web.

Código completo

Puedes ver todo el código en el siguiente repositorio:

This is a Next.js project bootstrapped with create-next-app.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying pages/index.js. The page auto-updates as you edit the file.

API routes can be accessed on http://localhost:3000/api/hello. This endpoint can be edited in pages/api/hello.js.

The pages/api directory is mapped to /api/*. Files in this directory are treated as API routes instead of React pages.

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from…


Crear una página de Política de Cookies

¡Espera un momento! Todavía queda un paso importante: crear una página donde expliques el uso que se le da a las cookies y las instrucciones para revocar los permisos y/o borrar los datos en caso de ser necesario.

Como idea, puedes echarle un vistazo a la publicación de la Agencia Estatal de Protección de Datos para saber qué debe incluir.


Exención de responsabilidades

Este post contiene información general sobre la configuración de Google Analytics y el cumplimiento con la legislación vigente de España al día de la fecha. Los requisitos legales podrían ser diferentes atendiendo al tipo de empresa, localización y finalidad de la recogida de datos, por lo que es importante que se revise y consulte con una persona experta las necesidades legales de cada sitio web.

Discussion (0)