Next.js: Vous ajoutez une balise de script GA?

Créé le 30 oct. 2016  ·  74Commentaires  ·  Source: vercel/next.js

Salut!

Je suis actuellement en train de convertir mon site Web en projet next.js et je ne parviens pas à comprendre comment ajouter la balise de script Google Analytics à la page. Des pensées?

À votre santé,
Robin

Commentaire le plus utile

Pas besoin de react-ga . Utilisez le gestionnaire de balises Google avec le composant <Head> pour injecter des analyses. Il y a quelques petites modifications au code du gestionnaire de balises google nécessaires pour le faire fonctionner dans nextjs / react:

<Head>
      <script dangerouslySetInnerHTML={{__html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
      })(window,document,'script','dataLayer','GTM-XXXXXX');`}} />
    </Head>
    <noscript dangerouslySetInnerHTML={{__html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" height="0" width="0" style="display:none;visibility:hidden;"></iframe>`}} />

image

Tous les 74 commentaires

paiement <Head>

@robinvdvleuten Je suggère de créer un composant GoogleTagManager et de l'inclure dans la tête ou juste après en fonction de votre choix d'implémentation.

comme les gens l'ont mentionné, vous pouvez utiliser la balise Head ou une solution conviviale comme https://github.com/react-ga/react-ga

Avez-vous des conseils pour faire fonctionner react -ga avec next.js?

@gtramontina cela devrait fonctionner. Sinon, je suis l'un des contributeurs react-ga , donc je pourrais vous aider

Pas besoin de react-ga . Utilisez le gestionnaire de balises Google avec le composant <Head> pour injecter des analyses. Il y a quelques petites modifications au code du gestionnaire de balises google nécessaires pour le faire fonctionner dans nextjs / react:

<Head>
      <script dangerouslySetInnerHTML={{__html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
      })(window,document,'script','dataLayer','GTM-XXXXXX');`}} />
    </Head>
    <noscript dangerouslySetInnerHTML={{__html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" height="0" width="0" style="display:none;visibility:hidden;"></iframe>`}} />

image

Je recommanderais une meilleure solution pour suivre la vue de la page côté client: autotrack. Voir https://github.com/MoOx/phenomic/issues/384 pour plus d'informations.

@impronunciable ce serait formidable d'avoir un exemple car après quelques recherches sur Google, je suis toujours confus 😃 Cela pourrait-il être rouvert?

  • @MoOx semble impliquer que Google AutoTrack à la place
  • mais Autotrack demande de créer une balise de script avec du code qui accède à l'objet window , donc cela ne fonctionne pas côté serveur
  • et de toute façon si vous utilisez un composant de réaction tel que react-ga, où doit-il être placé? Dans un render ? componentWillMount ? getInitialProps ? Ce n'est pas très clair car cela suppose en quelque sorte que vous utilisez react-router et chargez le code une seule fois pour toutes les pages.

Le suivi de page doit fonctionner à la fois lorsque la page est rendue par le serveur et lors de la navigation vers une autre page. Ce serait formidable de voir comment le tout devrait s'intégrer dans une application Next typique avec une tête, un HOC de mise en page, etc.

Ce serait également formidable de savoir si vous pensez qu'il existe une combinaison meilleure / plus simple / moins encombrante / plus à la pointe de la technologie que Next.js + Google Analytics Autotrack ...

Je peux enquêter sur ça

Le mar 17 janv.2017, 07:59 Sébastien Dubois [email protected]
a écrit:

@impronunciable https://github.com/impronunciable ce serait génial de
avoir un exemple car après quelques recherches sur Google, je suis toujours confus 😃 Cela pourrait-il
être rouvert?

  • @MoOx https://github.com/MoOx semble impliquer que react -ga n'est pas
    nécessaire, devrait utiliser Google AutoTrack
    https://github.com/googleanalytics/autotrack à la place
  • mais Autotrack demande de créer une balise de script avec du code qui
    accède à l'objet window, donc cela ne fonctionne pas côté serveur
  • et de toute façon si vous utilisez un composant réactif tel que react-ga, où devrait
    il être mis? Dans un rendu? componentWillMount? getInitialProps? Ce n'est pas
    super clair car cela suppose que vous utilisez react-router et chargez le
    code une seule fois pour toutes les pages.

Le suivi de page doit fonctionner à la fois lorsque la page est rendue par le serveur et
puis lors de la navigation vers une autre page. Ce serait formidable de voir comment
le tout devrait s'intégrer dans une application Next typique avec une tête, une page
mise en page HOC, etc.

Ce serait également formidable de savoir si vous pensez qu'il existe un meilleur / plus simple / moins
combinaison encombrante / plus à la pointe de la technologie que Next.js + Google
Suivi automatique Analytics ...

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/zeit/next.js/issues/160#issuecomment-273108099 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/AAKHp9-2bfLXj2hMGlNlkqUSRqEL7R2Cks5rTJ8kgaJpZM4KkXxa
.

À peu près sûr, l'autotrack est plus que suffisant, injecté uniquement du côté client - pas besoin de penser au côté serveur.

Voir https://github.com/MoOx/react-toulouse/commit/c42045d1001ab813c5d7eae5ab2f4f8c08c0025e pour un exemple. Il n'est pas utilisé ensuite, mais je suppose que cela devrait être facile à adapter.

Oui, nous ne voulons pas suivre les rendus du serveur, car cela obscurcira des choses comme l'emplacement.

Non vous ne le faites pas car elle sera gérée par le client: gardez à l'esprit qu'une page est demandée par le client et sera rendue dans le navigateur client :)

OK, je ne savais pas que le code ne devait pas fonctionner côté serveur. J'ai donc utilisé l'autotrack comme recommandé par @MoOx , je pense que cela devrait fonctionner: https://github.com/relatenow/relate/commit/50dc3f317eb3efa045d5bbe40d1a1a1ad1116458

Je n'ai pas encore confirmé s'il compte correctement les pages vues, c'est nouveau pour moi 😬 😄

Vous pouvez utiliser la vue «en temps réel» pour déboguer facilement GA.

@MoOx oui https://relate.now.sh en parallèle dans un autre onglet (0 utilisateur actif)

Je ne comprends toujours pas cela ... Je ne reçois aucune donnée avec le code que j'ai écrit.

Tous les exemples que je vois semblent exiger un <script href="https://www.google-analytics.com/analytics.js" async /> mais les choses dans Head ne semblent pas être exécutées dans le client? (mon console.log n'est pas imprimé dans la console du navigateur ...)

Un exemple serait tout de même très apprécié 🙂

Comment l'avez-vous fait fonctionner? J'ai essayé d'appeler une fonction de page vue sur componentDidMount .

La vérification GA de l' application de production échoue.

@luandro ne se souvient pas des détails, mais vous pouvez consulter le commit que j'ai lié ci-dessus si cela aide

Je l'ai fait et essayé. J'ai fait la même chose que vous, en appelant configureAnalytics en haut et page vue sur componentWillMount , mais toujours négatif sur GA Check .

Dans votre code, il ne semble pas que vous ayez connecté la page hoc n'importe où, n'est-ce pas?

@luandro Ajoutez simplement ga(‘set’, ‘page’, window.location.pathname); ga(‘send’, ‘pageview’); pour changer l'URL de l'événement de page vue.

Peut-être qu'il y a un moyen plus 'next.js' de faire cela, mais WRT exécutant des scripts sur la page, j'ai trouvé que si je créais Script composant

// modules/Script.js
export default ({children}) => (
  <script dangerouslySetInnerHTML={{__html: `(${children.toString()})();` }}></script>
);

Ensuite, je pourrais faire ceci qui a fonctionné pour moi:

import Document, { Head, Main, NextScript } from 'next/document'
import Script from '../modules/Script';

export default class MyDocument extends Document {

  render () {
    return (
      <html>
        <body>
          <Main />
          <Script>
            {
              () => {
                console.log('foo');
              }
            }
          </Script>
          <NextScript />
        </body>
      </html>
    )
  }
}

La mise en garde est que vous devez tout inclure dans une fonction.

Est-il possible de suivre les pages vues individuelles sans appeler explicitement le ga ('envoyer', 'page vue') sur chaque page. Si nous devons absolument le faire, où l'invoquons-nous pour avoir la certitude que ga a été chargé?

Est-il possible de lier les événements de changement d'itinéraire d'une manière ou d'une autre pour enregistrer les pages vues?

@karthikiyengar J'utilise react-ga comme suggéré par d'autres ci-dessus et j'enregistre les pages vues sur componentDidMount de chaque page.

import ReactGA from 'react-ga'

export const initGA = () => {
  console.log('GA init')
  ReactGA.initialize('UA-xxxxxxxx-x')
}
export const logPageView = () => {
  ReactGA.set({ page: window.location.pathname })
  ReactGA.pageview(window.location.pathname)
}
componentDidMount () {
    initGA()
    logPageView()
  }

@vinaypuppal est-il courant d'initGA pour chaque composant de page?

@rongierlach J'utilise un composant Layout qui appelle les méthodes initialize et pageview sur ReactGA dans componentDidMount() .

export default class extends Component {
  componentDidMount() {
    ReactGA.initialize('UA-1234567-1')
    ReactGA.pageview(document.location.pathname)
  }

  render() {
    return (
      <div>
        {this.props.children}
     </div>
    )
}

C'est la façon la plus propre de le faire, car si la page est rendue par le serveur, elle doit être initialisée. Je suis sûr qu'il existe un hook qui pourrait contourner l'initialisation si c'est le client rendu.

@notrab ne pourriez-vous pas potentiellement manquer les rendus superficiels? Votre application fera simplement la transition et votre composant de mise en page ne pourra pas être remonté. C'est ce que j'ai pour les attraper.

componentDidMount() {
    ReactGA.initialize('xx-xxxxxxx-x')
    let trackMe = true

    if (trackMe) {
      ReactGA.pageview(document.location.pathname)
      trackMe = false
    }

    Router.onRouteChangeStart = () => {
      NProgress.start()
      this.store.dispatch(transitionPage(true))
      trackMe = true
    }
    Router.onRouteChangeComplete = () => {
      NProgress.done()
      this.store.dispatch(transitionPage(false))
      if (trackMe) { ReactGA.pageview(document.location.pathname) }
    }
    Router.onRouteChangeError = () => {
      NProgress.done()
      this.store.dispatch(transitionPage(false))
    }

    this.store.dispatch(calculateResponsiveState(window))
  }

Essayer de faire fonctionner cela, mais toujours pas de réponse de Google Analytics. Voici mon code en react-ga.js :

import ReactGA from 'react-ga'

const dev = process.env.NODE_ENV !== 'production'

export const initGA = () => {
  ReactGA.initialize("UA-XXXXXXXXX-X", {
    debug: dev,
  })
}

export const trackPageView = (
  pageName = window.location.pathname + window.location.search
) => {
  ReactGA.set({page: pageName})
  ReactGA.pageview(pageName)
}

export const trackCustomEvent = (category, action) =>
  ReactGA.event({category, action})

export default undefined

Et ma page d'index:

import {initGA, trackPageView} from '../modules/react-ga.js'
[...]
Index.componentDidMount = function() {
    initGA()
    trackPageView()
}

avec le code UA remplacé par mon code réel, bien sûr.

@filostrato Comment l'avez-vous

@exogenesys J'ai fini par mettre ça dans utils/analytics.js :

import ReactGA from 'react-ga'

const dev = process.env.NODE_ENV !== 'production'

export const initGA = () => {
  ReactGA.initialize("UA-xxxxxxxxx-x", {
    debug: dev,
  })
}

export const logPageView = (
  pageName = window.location.pathname + window.location.search
) => {
  ReactGA.set({page: pageName})
  ReactGA.pageview(pageName)
}

export const trackCustomEvent = (category, action) =>
  ReactGA.event({category, action})

export default undefined

et j'ai changé mon Layout.js pour étendre React.Component :

export default class Layout extends React.Component {
    componentDidMount () {
      if (!window.GA_INITIALIZED) {
        initGA()
        window.GA_INITIALIZED = true
    }
    logPageView()
  }

  render () {
    return (
      <Main>
        <Header />
        {this.props.children}
      </Main>
    )
  }
}

Je n'ai pas trouvé de moyen de le faire fonctionner dans un composant qui utilise getInitialProps , mais puisque Layout.js cela ne fonctionnait pas très bien; Je ne sais pas quoi faire si je veux des statistiques plus détaillées, mais je traverserai ce pont quand j'y viendrai.

@filostrato Cela l'a fait. Merci beaucoup. :)

salut les gars

Je viens de traiter également de la mise en œuvre de GA sur mon site et c'est ce que j'ai proposé.

J'ai d'abord utilisé la solution de @notrab qui semblait propre et simple:

export default class extends Component {
  componentDidMount() {
    ReactGA.initialize('UA-XXXXXXX-X')
    ReactGA.pageview(document.location.pathname)
  }

  render() {
    …
  }
}

Cependant, j'ai remarqué:

  • componentDidMount été exécuté lorsque j'ai basculé entre des pages de types différents, donc la fonction initialize été appelée plusieurs fois
  • componentDidMount était _uniquement_ exécuté lorsque je basculais entre des pages de types différents, donc la fonction pageview n'a été appelée qu'alors => J'ai un type de page video sur mon site Web et j'ai vu dans la vue GA Live qui, lors du passage d'une page vidéo à une autre, seule la page vidéo initiale était suivie

J'ai créé un composant d'ordre supérieur pour résoudre ces deux problèmes. Pour le premier, j'ai utilisé la solution de @filostrato .

import React, { Component } from 'react';
import ReactGA from 'react-ga';
import Router from 'next/router';

const debug = process.env.NODE_ENV !== 'production';

export default (WrappedComponent) => (
  class GaWrapper extends Component {
    constructor (props) {
      super(props);
      this.trackPageview = this.trackPageview.bind(this);
    }

    componentDidMount() {
      this.initGa();
      this.trackPageview();
      Router.router.events.on('routeChangeComplete', this.trackPageview);
    }

    componentWillUnmount() {
      Router.router.events.off('routeChangeComplete', this.trackPageview);
    }

    trackPageview (path = document.location.pathname) {
      if (path !== this.lastTrackedPath) {
        ReactGA.pageview(path);
        this.lastTrackedPath = path;
      }
    }

    initGa () {
      if (!window.GA_INITIALIZED) {
        ReactGA.initialize('UA-XXXXXX-XX', { debug });
        window.GA_INITIALIZED = true;
      }
    }

    render() {
      return (
        <WrappedComponent {...this.props} />
      );
    }
  }
);

Et dans votre composant <Layout> / <PageWrapper> / <PageScaffold> ou comme vous l'appelez:

import GaWrapper from './ga-wrapper';

const PageScaffold = () => (…);

export default GaWrapper(PageScaffold);

Peut-être que cela aide n'importe qui.

Je n'aime pas l'appel de Router.router.events.… cependant, car cela ne fait pas partie de l'API documentée. Cependant, lorsque j'ai essayé d'appeler Router.onRouteChangeComplete ce qui devrait être le bon moyen , j'ai obtenu une ReferenceError parce que onRouteChangeComplete était undefined . Peut-être que la documentation est obsolète?

Cela a fonctionné pour moi dans un site Web next.js. Et j'ai contourné l'erreur «fenêtre non définie» que je rencontrais avec l'implémentation habituelle de react-ga.

La solution

Grâce au code de pageview utilisant le nouveau gtag google (qui remplace les scripts _universal analytics_):

pages/_document.js

import Document, { Head } from 'next/document';

const GA_TRACKING_ID = '..';

export default class MyDocument extends Document {
  render() {
    return (
      <html lang="en-AU">
        <Head>
          <script async src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`} />
          <script
            dangerouslySetInnerHTML={{
              __html: `
                window.dataLayer = window.dataLayer || [];
                function gtag(){dataLayer.push(arguments)};
                gtag('js', new Date());
                gtag('config', '${GA_TRACKING_ID}');
              `,
            }}
          />
        </Head>
        ...
      </html>
    );
  }
}

scaffold.js / layout.js / wraper.js / quel que soit le nom de votre projet:

import url from 'url';
import Router from 'next/router';

const GA_TRACKING_ID = '...';

const withPageViews = WrappedComponent =>
  class GaWrapper extends React.Component {
    componentDidMount() {
      // We want to do this code _once_ after the component has successfully
      // mounted in the browser only, so we use a special semiphore here.
      if (window.__NEXT_ROUTER_PAGEVIEW_REGISTERED__) {
        return;
      }

      window.__NEXT_ROUTER_PAGEVIEW_REGISTERED__ = true;
      let lastTrackedUrl = '';

      // NOTE: No corresponding `off` as we want this event listener to exist
      // for the entire lifecycle of the page
      // NOTE: This does _not_ fire on first page load. This is what we want
      // since GA already tracks a page view when the tag is first loaded.
      Router.router.events.on('routeChangeComplete', (newUrl = document.location) => {
        if (newUrl === lastTrackedUrl || !window.gtag) {
          return;
        }

        // Don't double track the same URL
        lastTrackedUrl = newUrl;

        // Believe it or not, this triggers a new pageview event!
        // https://developers.google.com/analytics/devguides/collection/gtagjs/single-page-applications
        window.gtag('config', GA_TRACKING_ID, {
          page_path: url.parse(newUrl).path,
        });
      });
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };

const PageScaffold = () => (…);

export default withPageViews(PageScaffold);

Pour quiconque arrive en retard à la fête, la raison pour laquelle la solution de componentDidMount . Les définir en dehors du composant semble résoudre le problème:

https://gist.github.com/trezy/e26cb7feb2349f585d2daf449411d0a4

@trezy lors de l'utilisation de gtag , il ne semble pas être nécessaire de import ReactGA from 'react-ga' .

J'ai utilisé votre exemple <script dangerouslySetInnerHtml={...} /> et j'ai juste ajouté cette ligne dans l'injection:

window.gaTrackingId = '${gaTrackingId}';

Ensuite, cette astuce légère a commencé à fonctionner:

Router.onRouteChangeComplete = () => {
  if (window.gtag) {
    window.gtag('config', window.gaTrackingId, {
      page_location: window.location.href,
      page_path: window.location.pathname,
      page_title: window.document.title,
    });
  }
};

Un assez gros analytics.js n'est plus récupéré, mais toutes les pages sont toujours suivies!

Comme ce n'est pas évident, il serait bon d'avoir un exemple dans le repo.

Ou un référentiel next-google-analytics 🕵️

@prichodko Merci beaucoup d'avoir mis en place cet exemple !!

trouvé assez belle lib, ajoutée au fichier de mise en page principal dans componentDidMount () et il semble fonctionner correctement. C'est bien documenté, pas de bousculade

https://www.npmjs.com/package/react-gtm-module

@andylacko En effet, je l'avais forké pour corriger quelques trucs, comme HTTPS par exemple: https://github.com/Vadorequest/react-gtm

Il suffit d'ajouter ma solution ici au cas où cela pourrait être utile pour quelqu'un plus tard.

J'ai utilisé react-ga mais la même logique devrait fonctionner avec d'autres outils ga.

GetInitialProps de _app.js est déclenché côté client chaque fois que l'utilisateur clique sur une nouvelle route. (La première fois, il s'exécutera côté serveur).

componentDidMount of _app.js s'exécute uniquement côté client.

Donc dans mon _app.js , j'ai ajouté les quelques lignes de code suivantes


static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);      
    }

    // client-side only, run on page changes, do not run on server (SSR)
    if (typeof(window) === "object") {
      ReactGA.pageview(ctx.asPath);
    }
    return { pageProps, router }
  }


  componentDidMount() {
    // client-side only, run once on mount
    ReactGA.initialize('UA-XXXXXXX-3');
    ReactGA.pageview(window.location.pathname + window.location.search);
  }

Lorsque la page est rendue sur le serveur, rien ne se passe dans getInitialProps car j'ai enveloppé le code GA dans typeof(window) === "object" .

Côté client, getInitialProps ne fonctionnera pas pour la première fois car tout est rendu par le serveur. GA est configuré dans componentDidMount côté client.

Les changements de route ultérieurs (même pour la même route) déclenchent getInitialProps côté client et l'événement ga est déclenché.

Il suffit d'ajouter ma solution ici au cas où cela pourrait être utile pour quelqu'un plus tard.

J'ai utilisé react-ga mais la même logique devrait fonctionner avec d'autres outils ga.

GetInitialProps de _app.js est déclenché côté client chaque fois que l'utilisateur clique sur une nouvelle route. (La première fois, il s'exécutera côté serveur).

componentDidMount of _app.js s'exécute uniquement côté client.

Donc dans mon _app.js , j'ai ajouté les quelques lignes de code suivantes


static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);      
    }

    // client-side only, run on page changes, do not run on server (SSR)
    if (typeof(window) === "object") {
      ReactGA.pageview(ctx.asPath);
    }
    return { pageProps, router }
  }


  componentDidMount() {
    // client-side only, run once on mount
    ReactGA.initialize('UA-XXXXXXX-3');
    ReactGA.pageview(window.location.pathname + window.location.search);
  }

Lorsque la page est rendue sur le serveur, rien ne se passe dans getInitialProps car j'ai enveloppé le code GA dans typeof(window) === "object" .

Côté client, getInitialProps ne fonctionnera pas pour la première fois car tout est rendu par le serveur. GA est configuré dans componentDidMount côté client.

Les changements de route ultérieurs (même pour la même route) déclenchent getInitialProps côté client et l'événement ga est déclenché.

Salut Will. L'inclusion de ReactGA dans votre webpack (car il est exécuté côté client) a-t-il un effet significatif sur la taille de votre build?

@ChrisEdson https://github.com/react-ga/react-ga la bibliothèque entière est compressée à 161 ko.

Hmm. C'est absolument énorme pour être honnête!

Le jeudi 28 février 2019 à 19 h 01, William Li [email protected] a écrit:

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga toute la bibliothèque est compressée à 161 Ko.

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/zeit/next.js/issues/160#issuecomment-468395136 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa
.

c'est le numéro indiqué sur GitHub pour toute la bibliothèque.
Comment vérifier la taille réelle une fois emballée dans l'application?

Envoyé de mon iPhone

Le 1 mars 2019, à 15h43, Chris Edson [email protected] a écrit:

Hmm. C'est absolument énorme pour être honnête!

Le jeudi 28 février 2019 à 19 h 01, William Li [email protected] a écrit:

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga toute la bibliothèque est compressée à 161 Ko.

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/zeit/next.js/issues/160#issuecomment-468395136 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa
.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, affichez-le sur GitHub ou désactivez le fil de discussion.

Ainsi, le script minifié fait 15 Ko. C'est assez petit.

Je vais analyser mon pack Web et je vais rendre compte de ce qu'il ajoute dans la pratique.

Dans une taille de paquet totale d'environ 500 Ko, mon ReactGA ajoute environ 27 Ko. Tellement petit dans le grand schéma des choses.

Il suffit d'ajouter ma solution ici au cas où cela pourrait être utile pour quelqu'un plus tard.

J'ai utilisé react-ga mais la même logique devrait fonctionner avec d'autres outils ga.

GetInitialProps de _app.js est déclenché côté client chaque fois que l'utilisateur clique sur une nouvelle route. (La première fois, il s'exécutera côté serveur).

componentDidMount of _app.js s'exécute uniquement côté client.

Donc dans mon _app.js , j'ai ajouté les quelques lignes de code suivantes


static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);      
    }

    // client-side only, run on page changes, do not run on server (SSR)
    if (typeof(window) === "object") {
      ReactGA.pageview(ctx.asPath);
    }
    return { pageProps, router }
  }


  componentDidMount() {
    // client-side only, run once on mount
    ReactGA.initialize('UA-XXXXXXX-3');
    ReactGA.pageview(window.location.pathname + window.location.search);
  }

Lorsque la page est rendue sur le serveur, rien ne se passe dans getInitialProps car j'ai enveloppé le code GA dans typeof(window) === "object" .

Côté client, getInitialProps ne fonctionnera pas pour la première fois car tout est rendu par le serveur. GA est configuré dans componentDidMount côté client.

Les changements de route ultérieurs (même pour la même route) déclenchent getInitialProps côté client et l'événement ga est déclenché.

Un problème qui se pose si vous utilisez NextJS 9 est que ceci avec la désactivation du prérendu automatique. Vous vous demandez s'il y a un meilleur endroit pour mettre le ReactGA.pageview(ctx.asPath); , le retirer de getInitialProps signifie que nous pouvons supprimer getInitialProps et ne pas forcer la pré-soumission automatique à se désinscrire comme indiqué ici: https : //err.sh/next.js/opt-out-automatic-prerendering.

Mise à jour: j'ai trouvé l'exemple with-google-analytics (https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics) et emprunté le bit à propos de: Router.events.on('routeChangeComplete', url => ReactGA.pageview(url)) Je dois tester cela pour m'assurer que l'URL est correcte mais qu'elle ressemble à la bonne manière. J'ai supprimé la méthode getInitialProps et ajouté ceci au-dessus de la déclaration de classe.

@GodOfGrandeur Cela semble prometteur, je vais essayer en prod. La version mentionnée ci-dessus n'a pas fonctionné ou semblait être ainsi https://medium.com/@austintoddj/using -google-analytics-with-next-js-423ea2d16a98 L'ajout de votre code dans _app.js semble se déclencher partout comme nécessaire et j'aime aussi que ce ne soit pas déclenché sur le serveur (ce n'aurait pas été un problème).

Pas besoin de tiers, si vous utilisez gtag, utilisez le code suivant que j'ai créé: -

<script
    async
    src="https://www.googletagmanager.com/gtag/js?id=%your code here%" >
</script>
<script dangerouslySetInnerHTML={
    { __html: `
        window.dataLayer = window.dataLayer || [];
        function gtag(){window.dataLayer.push(arguments)}
        gtag("js", new Date());
        gtag("config", "<%your code here%>");
    `}
}>
</script>

Une autre option consiste à utiliser useEffect() . J'ai fait cela dans mon fichier Layout.js .

useEffect(() => {
  if (process.env.NODE_ENV === 'production') {
    window.dataLayer = window.dataLayer || []
    function gtag() {
      dataLayer.push(arguments)
    }
    gtag('js', new Date())
    gtag('config', '{GOOGLE ANALYTICS CODE}', {
      page_location: window.location.href,
      page_path: window.location.pathname,
      page_title: window.document.title,
    })
  }
})

Et dans le <Head> :

<Head>
  <script async src="https://www.googletagmanager.com/gtag/js?id={GOOGLE ANALYTICS CODE}"></script>
</Head>

@reinink Je veux juste mentionner que vous voudrez peut-être passer un tableau vide comme deuxième accessoire à useEffect afin qu'il n'exécute la fonction qu'une seule fois après le rendu initial.

useEffect(() => {...}, [])

En développant la solution

import React, { useEffect } from 'react'
import Head from 'next/head'
const GoogleAnalyticsHOC = ({ children }) => {
  useEffect(() => {
    if (process.env.NODE_ENV === 'production') {
      window.dataLayer = window.dataLayer || []
      // eslint-disable-next-line
      function gtag() {
        window.dataLayer.push(arguments)
      }
      gtag('js', new Date())
      gtag('config', process.env.GOOGLE_ANALYTICS_ID, {
        page_location: window.location.href,
        page_path: window.location.pathname,
        page_title: window.document.title
      })
    }
  }, [])
  return (
    <>
      <Head>
        <script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GOOGLE_ANALYTICS_ID}`} />
      </Head>
      {children}
    </>
  )
}
export default GoogleAnalyticsHOC

Ce n'est pas largement testé mais cela fonctionne et me passe comme un visiteur en temps réel fonctionnant localement. :)

J'ai trouvé ce guide - est-ce une approche recommandée (utilise react-ga)?

Je dirais que la méthode recommandée est d'utiliser cet exemple officiel:

https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics

Il est déjà publié ici. Parfois, je souhaite que les problèmes de github ressemblent davantage à stackoverflow, une réponse acceptée et mise en surbrillance, juste après la question (quand il y a trop de messages et d'émojis, ce n'est pas suffisant. Une option consiste à restreindre les commentaires de ce message, afin que les gens créent un nouveau problème à la place. Et lors de la création, ils trouveront qu'un problème similaire a déjà été créé (grâce à la fonctionnalité "problèmes similaires"), et il a une réponse (mais quand même, la réponse avec les emojis est perdue quelque part au milieu d'une longue histoire, donc c'est pas très pratique pour trouver des réponses sur github).

Il est déjà publié ici. Parfois, je souhaite que les problèmes de github ressemblent davantage à stackoverflow, avoir une réponse acceptée et mise en évidence, juste après la question (quand il y a trop de messages et d'émojis, ce n'est pas suffisant ...

Github fait un prototypage sur l'onglet Discussions de ce dépôt.

Screenshot 2020-04-08 at 16 59 58

@janbaykara wow, vraiment? Nous pensons tous de la même manière :) J'espère qu'ils trouveront un moyen de traduire un problème en discussion, ou ce sera la même chose (si les fonctionnalités sont fusionnées avec les problèmes, et toutes les discussions existantes deviendront des problèmes). Mais merci pour la réponse!

@ 3lonious J'ai personnellement abandonné Google Analytics, car il ne fait pas du bon travail avec SPA en général. (très mauvaise expérience, surtout avec SSR + CSR et double événements difficiles à retracer)

En ce qui concerne Next.js, consultez https://github.com/UnlyEd/next-right-now/blob/v2-mst-aptd-gcms-lcz-sty/src/components/pageLayouts/Head.tsx (en utilisant next/Head ), c'est ainsi que j'inclus des balises de script dans mes applications.

N'hésitez pas à jeter un œil à NRN https://unlyed.github.io/next-right-now , il est censé être un bon exemple sur "comment faire X" avec Next.js et devrait vous éviter pas mal de maux de tête.

Je ne suis pas sûr de l'avoir compris, je ne vois aucune balise de script dans ce fichier?

C'est aussi une solution qui fonctionne. Je ne l'ai pas testé de manière approfondie, alors faites-le vous-même.

Dans pages/_document.js , ajoutez ceci à votre <Head> . Consultez les documents pour savoir comment remplacer le fichier de document .

<script async src='https://www.googletagmanager.com/gtag/js?id=YOUR_GA_TRACKING_ID'></script>
<script
    dangerouslySetInnerHTML={{
        __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments)}
            gtag('js', new Date());

            gtag('config', 'YOUR_GA_TRACKING_ID');
              `
      }}>
</script>

Il signale au moins le trafic vers mon compte GA.

Les balises
La solution ci-dessus fonctionne également, par expérience. (c'est comme ça que je faisais fonctionner GA)

ok merci les gars. je vais essayer de te revenir

ok je pense que je l'ai fait fonctionner

merci Anton. ok j'en ai un nouveau pour toi haha

J'ai une application de chat que j'utilise pour le service client mais cette balise de script ne fonctionne pas non plus? des idées?

ça me dit d'ajouter cette deuxième balise dans le corps? que faites-vous avec ça?
Screen Shot 2020-06-19 at 6 48 22 AM

Et le TBT? Si vous ajoutez Google Analytics, votre score de vitesse ralentira

Et le TBT? Si vous ajoutez Google Analytics, votre score de vitesse ralentira

C'est à cause de leur recommandation de placer le script avant le contenu. Si vous le placez sous le contenu, le score ne diminuera pas.

Personnellement, je ne vois pas de réels avantages à placer le script en premier. Si le chargement de la page était en quelque sorte interrompu et que le HTML ne se chargeait pas complètement et qu'il était annulé, alors je ne pourrais pas le compter comme un succès, peu importe.

Je travaille avec nextjs. J'essaye d'utiliser l'API de saisie semi-automatique de react google place. Et veut insérer ces balises de script de l'API? Où dois-je insérer ces balises de script?

_app.js

`` `js
importer ReactGA depuis "react-ga";

componentDidMount() {
  ReactGA.initialize("XX-XXXXXXXXX-X", { debug: false });
  ReactGA.set({ page: this.props.router.pathname });
  ReactGA.pageview(this.props.router.pathname);
  this.unlisten = this.props.router.events.on("routeChangeComplete", (router) => {
      ReactGA.set({ page: router });
      ReactGA.pageview(router);
    });
}

C'est hilarant. Non, en fait c'est triste. J'ai hâte que React, Next, tout l'écosystème meure.

Cette page vous a été utile?
0 / 5 - 0 notes