Búsqueda de sitios web

javascript - Integración de Google Analytics 4 en React TS


Entonces, actualmente uno puede elegir entre Universal Analytics y Google Analytics 4.

Mis argumentos sobre por qué usar Google Analytics 4:

  • Universal Analytics se retirará el 1 de julio de 2023, así que cuando haga una nueva configuración creo que tiene sentido optar ya por Google Analytics 4.
  • El paquete react-ga no funciona con GA-4 y, al parecer, no lo hará. El react-ga está en mantenimiento pasivo y no se actualizará para soportar GA-4 a menos que alguien más haga un PR.
  • Pero existe el módulo de React Google Analytics 4, en resumen react-ga4, que funciona con GA-4

Así que creé una propiedad en GA y seguí esta guía, instalé el módulo y simplemente lo inicialicé en mi archivo principal index.tsx con ReactGA.initialize. El ID no se almacena en un archivo de entorno ya que es público de todos modos según esta respuesta. Una prueba en localhost muestra que GA recoge los datos.

No se necesita más código. GA4 es lo suficientemente inteligente como para medir todas esas interacciones automáticamente. No necesitas preocuparte por codificarlas en tu proyecto. GA4 mide automáticamente las interacciones y el contenido en los sitios además de la medición estándar de visitas a la página: Visitas a páginas, desplazamientos, clics salientes, búsqueda en el sitio, interacción con videos y descargas de archivos. Ver: Eventos de medición mejorada

Cualquier otro evento basado en casos de uso, tenemos que codificarlo nosotros mismos. Eso básicamente no ha cambiado desde Universal Analytics.

Entonces mi 1. Pregunta es: ¿Es correcta la información que he recopilado? ¿La integrarías de otra manera? ¿O me falta algo?

En general, me pregunto cuál es el beneficio de usar la biblioteca?

--> Alternativamente, podría hacer para la integración: Agregar la etiqueta global del sitio directamente a sus páginas web

¿Cuál es el mejor enfoque?

Ahora la segunda parte, en el primer fragmento de código ves la inicialización de react-ga4 en mi index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import ReactGA from 'react-ga4';

ReactGA.initialize('G-XXXXXXXX');

ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById('root')
); 

Una prueba en localhost muestra que los datos se captan en el panel de GA. ¡Perfecto!

Pero luego está el problema con los bloqueos de Adblocker. Normalmente, la aplicación se bloquea si alguien tiene un bloqueador de anuncios (el bloqueador de anuncios bloquea los endpoints de solicitudes de análisis, sin manejo de errores, etc.) y para mitigar esto detectamos si el script no se cargó y, por lo tanto, deducimos si el usuario tiene un bloqueador de anuncios que está impidiendo que se cargue el script de GA. En mi código de ejemplo, simplemente lo ignoro y cargo la aplicación... en otros escenarios, supongo que podrías invocar un modal para decirles que lo desactiven (por supuesto, eso vendría con código adicional). Tomado de la respuesta de spencer741.

index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import ReactGA from 'react-ga4';

(async _ => {
  
    await ReactGA.initialize('G-XXXXXXXXX')
    .then(res => console.log("Analytics Success."))
    .catch(err => console.log("Analytics Failure."))
    .finally(() => {
      ReactDOM.render(
        <React.StrictMode>
            <App />
        </React.StrictMode>,
        document.getElementById('root')
      );
    });
    })();

Sé que esto lanza errores en Typescript en este momento:

Property 'then' does not exist on type 'void'.

Property 'catch' does not exist on type 'void'.

Property 'finally' does not exist on type 'void'.
'res' is declared but its value is never read.
Parameter 'res' implicitly has an 'any' type. 
'err' is declared but its value is never read.
Parameter 'err' implicitly has an 'any' type.

Pero antes de intentar resolver los errores, me gustaría saber si ¿Es esta una solución viable para evitar posibles errores con el bloqueador de anuncios?

Respuesta #1

Dado que no hay otras respuestas, intentaré responder a las preguntas del OP lo mejor que pueda.

1. ¿Es correcta la información que reuní? Sí y no. Aunque ambas bibliotecas hacen lo que dicen hacer, tomaría "GA4 es lo suficientemente inteligente como para medir todas esas interacciones automáticamente" con un grano de sal, ya que ambas requieren algo de configuración para rastrear eventos personalizados o múltiples trackingId y ajustar finamente tu analítica. Consulta el repositorio react-ga4 y la demostración de react-ga.

2. ¿Lo integrarías de otra manera? ¿O me estoy perdiendo de algo? Si por "otra manera" te referías a algo diferente a los ejemplos de la pregunta, sí. Como se mencionó en los comentarios, un enfoque mejor sería encapsular toda tu lógica de GA, ya sea con un Componente de Orden Superior o un hook personalizado (ejemplos abajo).

3. En general, me pregunto cuál es el beneficio de usar la biblioteca? Creo que depende de las necesidades de tu proyecto. Si estás trabajando en un proyecto temporal o un producto mínimo viable (MVP) que puede que no esté en producción dentro de un año, podrías estar mejor con react-ga ya que ha sido probado en combate y actualmente tiene 600k descargas por semana en NPM. Si no, actualizar tu base de código a react-ga4 podría ayudar a minimizar la deuda técnica en el futuro y aprovechar las actualizaciones de Google Analytics 4.

4. ¿Cuál es el mejor enfoque? Según las respuestas de GA4, actualmente hay 8 eventos que puedes personalizar aún más. Veamos cómo podríamos implementar un hook personalizado con react-ga4:

ga4.ts
import ga4 from 'react-ga4'

const TRACKING_ID = 'G-XXXXXXXXX-X'
const isProduction = process.env.NODE_ENV === 'production'

export const init = () => ga4.initialize(TRACKING_ID, { 
  testMode: !isProduction 
})

export const sendEvent = (name: string) => ga4.event('screen_view', {
  app_name: "myApp",
  screen_name: name,
})

export const sendPageview = (path: string) => ga4.send({ 
  hitType: 'pageview', 
  page: path 
})
useAnalytics.ts
import React from 'react'
import { useLocation } from 'react-router-dom'

import * as analytics from './ga4'

export function useAnalytics() {
  const location = useLocation()

  React.useEffect(() => {
    analytics.init()
  }, [])

  React.useEffect(() => {
    const path = location.pathname + location.search
    analytics.sendPageview(path)
  }, [location])
}

export default useAnalytics

Alternativamente, si no estás usando react-router-dom, podrías obtener la ruta desde el objeto global window, de la siguiente manera:

analytics.sendPageview(window.location.pathname)

O con Next.js:

const router = useRouter()
analytics.sendPageview(router.asPath)

Uso

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Switch } from 'react-router-dom'

import { useAnalytics } from './useAnalytics'

function App() {
  useAnalytics() // add it here
  return <Switch>...</Switch>
}

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  node
)

5. ¿Es esta una solución viable para evitar posibles errores con el bloqueador de anuncios? Hay un tutorial en FreeCodeCamp.org que muestra cómo usar proxies para evitar los bloqueadores de anuncios. También podrías usar bibliotecas como FuckAdBlock, BlockAdBlock o adblock-detect-react para verificar si el bloqueo de anuncios está activado en una página e inicializar react-ga4 de manera condicional. Como recordatorio: normalmente se tarda 24/48 horas en recopilar los datos de analítica. Las cuentas nuevas de GA pueden tardar unos días antes de comenzar a registrar datos.

import React from 'react'
import { useDetectAdBlock } from 'adblock-detect-react'

const useAnalytics = () => {
  const adBlockDetected = useDetectAdBlock()

  React.useEffect(() => {
    if(!adBlockDetected) analytics.init()
  }, [])

  React.useEffect(() => {
    if (!adBlockDetected) { 
      analytics.sendPageview(window.location.pathname)
    }
  } [adBlockDetected, path])
}

¡Espero que eso ayude! Saludos.

Artículos relacionados