Next.js: GA-Skript-Tag hinzufügen?

Erstellt am 30. Okt. 2016  ·  74Kommentare  ·  Quelle: vercel/next.js

Hallo!

Ich konvertiere derzeit meine Website in ein next.js-Projekt und kann nicht herausfinden, wie das Google Analytics-Skript-Tag zur Seite hinzugefügt wird. Irgendwelche Gedanken?

Prost,
Robin

Hilfreichster Kommentar

Keine Notwendigkeit für react-ga . Verwenden Sie den Google Tag Manager mit der Komponente <Head> , um Analysen zu injizieren. Es gibt einige kleine Änderungen am Google Tag Manager-Code, die erforderlich sind, damit er in nextjs / react funktioniert:

<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

Alle 74 Kommentare

Kasse <Head>

@robinvdvleuten Ich würde vorschlagen, eine GoogleTagManager-Komponente zu erstellen und diese in den Kopf oder direkt danach aufzunehmen, abhängig von Ihrer Implementierungsauswahl.

Wie bereits erwähnt, können Sie das Head -Tag oder eine reaktionsfreundliche Lösung wie https://github.com/react-ga/react-ga verwenden

Irgendwelche Tipps, wie man mit next.js reagieren kann?

@ gtramontina sollte es funktionieren. Ansonsten bin ich einer der react-ga Mitwirkenden, also könnte ich dabei helfen

Keine Notwendigkeit für react-ga . Verwenden Sie den Google Tag Manager mit der Komponente <Head> , um Analysen zu injizieren. Es gibt einige kleine Änderungen am Google Tag Manager-Code, die erforderlich sind, damit er in nextjs / react funktioniert:

<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

Ich würde eine bessere Lösung empfehlen, um die Seitenansicht des Clients zu verfolgen: Autotrack. Weitere Informationen finden Sie unter https://github.com/MoOx/phenomic/issues/384 .

@impronunciable es wäre toll, ein Beispiel zu haben, da ich nach einigem googeln immer noch verwirrt bin 😃 Könnte dies wieder geöffnet werden?

  • @MoOx scheint zu implizieren, dass Sie stattdessen
  • Autotrack weist jedoch an, ein Skript-Tag mit Code zu erstellen, das auf das Objekt window zugreift, sodass dies serverseitig nicht funktioniert
  • und überhaupt, wenn eine Reaktionskomponente wie React-Ga verwendet wird, wo sollte sie platziert werden? In einem render ? componentWillMount ? getInitialProps ? Es ist nicht sehr klar, da davon ausgegangen wird, dass Sie den React-Router verwenden und den Code für alle Seiten ein einziges Mal laden.

Die Seitenverfolgung sollte sowohl beim Server-Rendering als auch beim Navigieren zu einer anderen Seite funktionieren. Es wäre großartig zu sehen, wie sich das Ganze in eine typische Next-App mit einem Kopf, einem Seitenlayout-HOC usw. integrieren lässt.

Es wäre auch toll zu wissen, ob Sie der Meinung sind, dass es eine bessere / einfachere / weniger umständliche / modernere Kombination als Next.js + Google Analytics Autotrack gibt ...

Ich kann das untersuchen

Am Dienstag, 17. Januar 2017, 07:59 Uhr Sébastien Dubois [email protected]
schrieb:

@impronunciable https://github.com/impronunciable wäre es toll zu
Ich habe ein Beispiel, denn nach einigem googeln bin ich immer noch verwirrt
wieder geöffnet werden?

  • @MoOx https://github.com/MoOx scheint zu implizieren, dass React -Ga dies nicht ist
    notwendig, sollte Google AutoTrack verwenden
    https://github.com/googleanalytics/autotrack stattdessen
  • Autotrack weist jedoch an, ein Skript-Tag mit Code zu erstellen, der
    greift auf das Fensterobjekt zu, sodass es serverseitig nicht funktioniert
  • und auf jeden Fall, wenn eine Reaktionskomponente wie React-Ga verwendet wird, wo sollte
    es gesetzt werden? In einem Render? componentWillMount? getInitialProps? Es ist nicht
    Super klar, da es davon ausgeht, dass Sie einen React-Router verwenden und den laden
    Code ein einziges Mal für alle Seiten.

Die Seitenverfolgung sollte sowohl funktionieren, wenn die Seite vom Server gerendert wird, als auch
dann beim Navigieren zu einer anderen Seite. Es wäre toll zu sehen wie
Das Ganze sollte in eine typische Next-App mit einem Kopf, einer Seite, integriert werden
Layout HOC usw.

Wäre auch toll zu wissen, ob du denkst, es gibt ein besseres / einfacheres / weniger
umständliche / modernere Kombination als Next.js + Google
Analytics Autotrack ...

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/zeit/next.js/issues/160#issuecomment-273108099 oder stumm schalten
der Faden
https://github.com/notifications/unsubscribe-auth/AAKHp9-2bfLXj2hMGlNlkqUSRqEL7R2Cks5rTJ8kgaJpZM4KkXxa
.

Ziemlich sicher, dass Autotrack mehr als genug ist und nur auf der Clientseite injiziert wird - Sie müssen nicht über die Serverseite nachdenken.

Ein Beispiel finden Sie unter https://github.com/MoOx/react-toulouse/commit/c42045d1001ab813c5d7eae5ab2f4f8c08c0025e . Es wird nicht als nächstes verwendet, aber ich denke, es sollte einfach anzupassen sein.

Ja, wir wollen keine Server-Renderings verfolgen, da dies Dinge wie den Standort verschleiern wird.

Nein, das tust du nicht, da es vom Client verwaltet wird: Beachten Sie, dass eine Seite vom Client angefordert und im Client-Browser gerendert wird :)

OK, ich wusste nicht, dass der Code nicht serverseitig ausgeführt werden sollte. Daher habe ich Autotrack verwendet, wie von @MoOx empfohlen. Ich denke, dies sollte funktionieren: https://github.com/relatenow/relate/commit/50dc3f317eb3efa045d5bbe40d1a1a1ad1116458

Nur noch nicht bestätigt, ob die Seitenaufrufe korrekt gezählt werden, das ist neu für mich 😬 😄

Sie können die "Echtzeit" -Ansicht verwenden, um GA einfach zu debuggen.

@MoOx Ja, das ist es, was mich stört. Ich sehe nichts im Echtzeitfenster, wenn ich https://relate.now.sh parallel auf einer anderen Registerkarte besuche (0 aktive Benutzer).

Ich verstehe das immer noch nicht ... Ich bekomme keine Daten mit dem Code, den ich geschrieben habe.

Alle Beispiele, die ich sehe, scheinen ein <script href="https://www.google-analytics.com/analytics.js" async /> zu erfordern, aber Dinge im Kopf scheinen nicht im Client ausgeführt zu werden? (Mein console.log wird nicht in der Browserkonsole gedruckt ...)

Ein Beispiel wäre immer noch sehr dankbar 🙂

Ah, es hat funktioniert, indem ich auf React-Ga switching umgeschaltet habe

https://github.com/relatenow/relate/commit/a9d2bce46e5314075af7c12bbaa0266865ff25da

screen shot 2017-01-18 at 14 01 28

Wie haben Sie es zum Laufen gebracht? Ich habe versucht, eine Seitenaufruffunktion für componentDidMount aufzurufen.

Die Produktions-App GA Check schlägt fehl.

@luandro kann sich nicht an die Details erinnern, aber Sie können sich das oben verlinkte Commit ansehen, wenn es hilft

Ich habe es versucht. Ich habe das Gleiche getan wie Sie, indem ich oben configureAnalytics und oben den Seitenaufruf componentWillMount , aber bei GA Check immer noch negativ geworden

In Ihrem Code scheint es nicht so, als hätten Sie tatsächlich irgendwo eine Seite hoc verbunden , oder?

@luandro Fügen Sie einfach ga(‘set’, ‘page’, window.location.pathname); ga(‘send’, ‘pageview’); , um die URL des Seitenaufrufereignisses zu ändern.

Vielleicht gibt es eine 'next.js'-Möglichkeit, dies zu tun, aber WRT, das Skripte auf der Seite ausführt, stellte ich fest, dass, wenn ich eine Script -Komponente wie folgt erstellte:

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

Dann könnte ich das tun, was für mich funktioniert hat:

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>
    )
  }
}

Die Einschränkung ist, dass Sie alles in eine Funktion einschließen müssen.

Ist es möglich, einzelne Seitenaufrufe zu verfolgen, ohne explizit das ga ('send', 'pageview') auf jeder Seite aufzurufen? Wenn wir es unbedingt tun müssen, wo rufen wir es auf, wenn wir sicher sind, dass ga geladen wurde?

Ist es möglich, Routenänderungsereignisse auf irgendeine Weise zu verknüpfen, um Seitenaufrufe zu protokollieren?

@karthikiyengar Ich verwende react-ga wie von anderen oben vorgeschlagen, und protokolliere Seitenaufrufe auf componentDidMount jeder Seite.

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 ist es üblich, für jede Seitenkomponente initGA zu verwenden?

@rongierlach Ich verwende eine Layout -Komponente, die die Methoden initialize und pageview für ReactGA innerhalb von componentDidMount() aufruft.

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

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

Dies ist der sauberste Weg, den ich bisher gemacht habe, als ob die Seite vom Server gerendert wird und initialisiert werden muss. Ich bin sicher, dass es einen Hook gibt, der die Initialisierung umgehen könnte, wenn der Client gerendert wird.

@notrab Könnten Sie möglicherweise nicht die flachen

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))
  }

Der Versuch, dies zum Laufen zu bringen, aber immer noch keine Antwort von Google Analytics. Dies ist mein Code in 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

Und meine Indexseite:

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

Natürlich wird der UA-Code durch meinen tatsächlichen Code ersetzt.

@filostrato Wie hast du das

@exogenesys Endete damit, dies in 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

und habe meine Layout.js geändert, um 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>
    )
  }
}

Ich habe keine Möglichkeit gefunden, es in einer Komponente zum Laufen zu bringen, die getInitialProps , aber da Layout.js nicht gut funktioniert hat; Ich bin mir nicht sicher, was ich tun soll, wenn ich detailliertere Statistiken möchte, aber ich werde diese Brücke überqueren, wenn ich dazu komme.

@filostrato Das hat es geschafft. Vielen Dank. :) :)

Hallo Leute

Ich habe mich gerade auch mit der Implementierung von GA auf meiner Website befasst, und das habe ich mir ausgedacht.

Zuerst habe ich die Lösung von @notrab verwendet , die sauber und unkompliziert schien:

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

  render() {
    …
  }
}

Mir ist jedoch aufgefallen:

  • componentDidMount wurde ausgeführt, als ich zwischen Seiten verschiedener Typen gewechselt habe, daher wurde die Funktion initialize mehrmals aufgerufen
  • componentDidMount wurde _nur_ ausgeführt, als ich zwischen Seiten verschiedener Typen gewechselt habe, daher wurde die Funktion pageview erst dann aufgerufen => Ich habe einen Pagetyp video auf meiner Website und habe gesehen In der GA Live-Ansicht wurde beim Umschalten zwischen verschiedenen Videoseiten nur die ursprüngliche Videoseite verfolgt

Ich habe eine Komponente höherer Ordnung erstellt, um diese beiden Probleme anzugehen. Für den ersten habe ich die Lösung von @filostrato verwendet.

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} />
      );
    }
  }
);

Und in Ihrer <Layout> / <PageWrapper> / <PageScaffold> -Komponente oder wie auch immer Sie es nennen:

import GaWrapper from './ga-wrapper';

const PageScaffold = () => (…);

export default GaWrapper(PageScaffold);

Vielleicht hilft das jedem.

Ich mag den Aufruf von Router.router.events.… allerdings nicht, da dies nicht Teil der dokumentierten API ist. Als ich jedoch versuchte, Router.onRouteChangeComplete aufzurufen, was der richtige Weg sein sollte , bekam ich einen ReferenceError, weil onRouteChangeComplete undefined . Vielleicht ist die Dokumentation veraltet?

Dies hat bei mir auf einer next.js-Website funktioniert. Und habe den Fehler "Fenster nicht definiert" umgangen, auf den ich bei der üblichen Implementierung von "React-Ga" gestoßen bin.

@osartun Lösung hat bei mir funktioniert. Vielen Dank! 👍

Dank des Codes von pageview -Ereignissen mit Googles neuen gtag (die die _universal Analytics_-Skripte ersetzen) entwickeln:

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 / wie auch immer Ihr Projekt es nennt:

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

Für alle, die zu spät zur Party kommen, funktioniert die Lösung von componentDidMount . Das Definieren außerhalb der Komponente scheint das Problem zu beheben:

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

@trezy Bei Verwendung von gtag scheint es nicht erforderlich zu sein, import ReactGA from 'react-ga' .

Ich habe Ihr <script dangerouslySetInnerHtml={...} /> Beispiel verwendet und nur diese eine Zeile in die Injektion eingefügt:

window.gaTrackingId = '${gaTrackingId}';

Danach begann dieser leichte Trick zu funktionieren:

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,
    });
  }
};

Ein ziemlich großes analytics.js wird nicht mehr abgerufen, aber alle Seiten werden noch verfolgt!

Da dies nicht offensichtlich ist, wäre es gut, ein Beispiel im Repo zu haben.

Oder ein Next-Google-Analytics-Repository 🕵️

@prichodko Vielen Dank, dass Sie dieses Beispiel zusammengestellt haben !!

fand ziemlich nette lib, wurde zur Hauptlayoutdatei in componentDidMount () hinzugefügt und es scheint korrekt zu funktionieren. Es ist gut dokumentiert, keine Hektik

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

@andylacko In der Tat hatte ich es gegabelt, um ein paar Dinge zu reparieren, wie zum Beispiel HTTPS: https://github.com/Vadorequest/react-gtm

Fügen Sie hier einfach meine Lösung hinzu, falls sie später für jemanden nützlich sein könnte.

Ich habe React-Ga verwendet, aber die gleiche Logik sollte mit anderen Ga-Tools funktionieren.

_app.js 's getInitialProps wird auf der Clientseite ausgelöst, wenn Benutzer auf eine neue Route klicken. (Zum ersten Mal wird es auf der Serverseite ausgeführt).

componentDidMount von _app.js nur auf der Clientseite ausgeführt.

Also habe ich in meinem _app.js die folgenden Codezeilen hinzugefügt


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);
  }

Wenn die Seite auf dem Server gerendert wird, passiert in getInitialProps nichts, da ich den GA-Code in typeof(window) === "object" .

Auf der Clientseite wird getInitialProps nicht zum ersten Mal ausgeführt, da alles vom Server gerendert wird. GA wird auf der Clientseite innerhalb von componentDidMount .

Nachfolgende Routenänderungen (auch für dieselbe Route) lösen auf der Clientseite getInitialProps aus und ein Ereignis wird ausgelöst.

Fügen Sie hier einfach meine Lösung hinzu, falls sie später für jemanden nützlich sein könnte.

Ich habe React-Ga verwendet, aber die gleiche Logik sollte mit anderen Ga-Tools funktionieren.

_app.js 's getInitialProps wird auf der Clientseite ausgelöst, wenn Benutzer auf eine neue Route klicken. (Zum ersten Mal wird es auf der Serverseite ausgeführt).

componentDidMount von _app.js nur auf der Clientseite ausgeführt.

Also habe ich in meinem _app.js die folgenden Codezeilen hinzugefügt


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);
  }

Wenn die Seite auf dem Server gerendert wird, passiert in getInitialProps nichts, da ich den GA-Code in typeof(window) === "object" .

Auf der Clientseite wird getInitialProps nicht zum ersten Mal ausgeführt, da alles vom Server gerendert wird. GA wird auf der Clientseite innerhalb von componentDidMount .

Nachfolgende Routenänderungen (auch für dieselbe Route) lösen auf der Clientseite getInitialProps aus und ein Ereignis wird ausgelöst.

Hey Will. Hat die Aufnahme von ReactGA in Ihr Webpack (da es clientseitig ausgeführt wird) einen erheblichen Einfluss auf Ihre Build-Größe?

@ChrisEdson https://github.com/react-ga/react-ga Die gesamte Bibliothek ist mit 161 KB komprimiert.

Hmm. Das ist absolut riesig, um ehrlich zu sein!

Am Donnerstag, den 28. Februar 2019 um 19:01 Uhr schrieb William Li [email protected] :

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga Die gesamte Bibliothek ist mit 161 KB komprimiert.

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/zeit/next.js/issues/160#issuecomment-468395136 oder stumm schalten
der Faden
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa
.

Das ist die auf GitHub aufgeführte Nummer für die gesamte Bibliothek.
Wie überprüfe ich die tatsächliche Größe, sobald sie in der App verpackt ist?

von meinem Iphone gesendet

Am 1. März 2019, um 15:43 Uhr, schrieb Chris Edson [email protected] :

Hmm. Das ist absolut riesig, um ehrlich zu sein!

Am Donnerstag, den 28. Februar 2019 um 19:01 Uhr schrieb William Li [email protected] :

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga Die gesamte Bibliothek ist mit 161 KB komprimiert.

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/zeit/next.js/issues/160#issuecomment-468395136 oder stumm schalten
der Faden
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa
.

- -
Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

Das minimierte Skript ist also 15 KB groß. Das ist ziemlich klein.

Ich werde mein Webpack bündelweise analysieren und berichten, wie viel es in der Praxis hinzufügt.

Innerhalb einer Gesamtpaketgröße von ~ 500 KB fügt mein ReactGA etwa 27 KB hinzu. So ziemlich klein im großen Schema der Dinge.

Fügen Sie hier einfach meine Lösung hinzu, falls sie später für jemanden nützlich sein könnte.

Ich habe React-Ga verwendet, aber die gleiche Logik sollte mit anderen Ga-Tools funktionieren.

_app.js 's getInitialProps wird auf der Clientseite ausgelöst, wenn Benutzer auf eine neue Route klicken. (Zum ersten Mal wird es auf der Serverseite ausgeführt).

componentDidMount von _app.js nur auf der Clientseite ausgeführt.

Also habe ich in meinem _app.js die folgenden Codezeilen hinzugefügt


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);
  }

Wenn die Seite auf dem Server gerendert wird, passiert in getInitialProps nichts, da ich den GA-Code in typeof(window) === "object" .

Auf der Clientseite wird getInitialProps nicht zum ersten Mal ausgeführt, da alles vom Server gerendert wird. GA wird auf der Clientseite innerhalb von componentDidMount .

Nachfolgende Routenänderungen (auch für dieselbe Route) lösen auf der Clientseite getInitialProps aus und ein Ereignis wird ausgelöst.

Ein Problem, das bei Verwendung von NextJS 9 auftritt, besteht darin, dass das automatische Vorrendern deaktiviert ist. Wenn wir uns fragen, ob es einen besseren Ort gibt, um die ReactGA.pageview(ctx.asPath); Wenn Sie sie aus getInitialProps entfernen, können Sie getInitialProps entfernen und das automatische Vorrendern nicht wie hier beschrieben zum Deaktivieren zwingen: https : //err.sh/next.js/opt-out-automatic-prerendering.

Update: Ich habe das With-Google-Analytics-Beispiel gefunden (https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics) und das Bit ausgeliehen über: Router.events.on('routeChangeComplete', url => ReactGA.pageview(url)) Ich muss dies testen, um sicherzustellen, dass die URL richtig ist, aber wie der richtige Weg aussieht. Ich habe die getInitialProps -Methode entfernt und diese über der Klassendeklaration hinzugefügt.

@GodOfGrandeur Das klingt https://medium.com/@austintoddj/using -Google-Analytik-mit-next-js-423ea2d16a98 Hinzufügen von Code in _app.js scheint überall auslösen wie nötig und ich mag auch, dass es nicht auf dem Server ausgelöst wird (hätte es nicht, obwohl es ein Problem ist).

Keine Notwendigkeit für Dritte. Wenn Sie gtag verwenden, verwenden Sie den folgenden Code, den ich erstellt habe: -

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

Eine andere Option ist die Verwendung von useEffect() . Ich habe dies in meiner Layout.js -Datei getan.

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,
    })
  }
})

Und in den <Head> :

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

@reinink Ich möchte nur erwähnen, dass Sie möglicherweise ein leeres Array als zweite Requisite an useEffect möchten, damit die Funktion nach dem ersten Rendern nur einmal ausgeführt wird.

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

Als Erweiterung der @ reinink- Lösung sehen Sie hier ein funktionierendes HOC, mit dem ich meine -vorlagen verpacke.

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

Es ist nicht ausgiebig getestet, aber es funktioniert und übergibt mich als Echtzeitbesucher, der lokal läuft. :) :)

Ich habe diesen Leitfaden gefunden - ist dies ein empfohlener Ansatz (verwendet React-Ga)?

Ich würde empfehlen, dieses offizielle Beispiel zu verwenden:

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

Es ist bereits hier gepostet. Manchmal möchte ich, dass Github-Probleme eher einem Stackoverflow ähneln und eine Antwort direkt nach der Frage akzeptiert und hervorgehoben wird (wenn zu viele Nachrichten und Emojis nicht ausreichen. Eine Möglichkeit besteht darin, das Kommentieren dieses Beitrags einzuschränken, damit die Benutzer ein neues Problem erstellen Stattdessen werden sie beim Erstellen feststellen, dass bereits ein ähnliches Problem erstellt wurde (dank der Funktion "Ähnliche Probleme"), und es hat eine Antwort (aber die Antwort mit Emojis geht irgendwo in der Mitte der langen Geschichte verloren, also ist es so nicht sehr bequem, um Antworten auf github zu finden).

Es ist bereits hier gepostet. Manchmal möchte ich, dass Github-Probleme eher einem Stackoverflow ähneln und eine Antwort direkt nach der Frage akzeptiert und hervorgehoben wird (wenn zu viele Nachrichten und Emojis nicht ausreichen ...

Github erstellt einen Prototyp auf der Registerkarte " Diskussionen" dieses Repos.

Screenshot 2020-04-08 at 16 59 58

@janbaykara wow, wirklich? Wir alle denken gleich :) Ich hoffe, sie werden einen Weg finden, ein Problem irgendwie in eine Diskussion zu übersetzen, oder es wird dasselbe sein (wenn die Funktionalität zu Problemen zusammengeführt wird und alle vorhandenen Diskussionen zu Problemen werden). Aber danke für die Antwort!

@ 3lonious Ich habe Google Analytics persönlich über

Informationen zu Next.js finden Sie unter https://github.com/UnlyEd/next-right-now/blob/v2-mst-aptd-gcms-lcz-sty/src/components/pageLayouts/Head.tsx (mit next/Head ), so füge ich Skript-Tags in meine Apps ein.

Zögern Sie nicht, sich NRN https://unlyed.github.io/next-right-now anzusehen. Es soll ein gutes Beispiel dafür sein, wie man X mit Next.js macht und sollte Ihnen einige Kopfschmerzen ersparen.

Ich bin nicht sicher, ob ich es bekomme. Ich sehe keine Skript-Tags in dieser Datei.

Dies ist auch eine Lösung, die funktioniert. Ich habe es nicht ausgiebig getestet, also mach das bitte selbst.

Fügen Sie dies in pages/_document.js zu Ihrem <Head> . Informationen zum Überschreiben der Dokumentdatei finden Sie in den Dokumenten .

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

Es meldet mindestens Datenverkehr an mein GA-Konto.

@ 3lonious Script-Tags und Style-Tags funktionieren auf die gleiche Weise.
Die obige Lösung funktioniert auch aus Erfahrung. (So ​​habe ich GA zum Laufen gebracht)

ok danke jungs. Ich werde versuchen, mich bei Ihnen zu melden

Ok, ich glaube, ich habe es zum Laufen gebracht

danke Anton. Ok, ich habe eine neue für dich, haha

Ich habe eine Chat-App, die ich für den Kundenservice verwende, aber das Skript-Tag funktioniert auch nicht? irgendwelche Ideen?

Es sagt mir, ich soll dieses zweite Tag in den Körper einfügen? was machst du damit
Screen Shot 2020-06-19 at 6 48 22 AM

Wie wäre es mit TBT? Wenn Sie Google Analytics hinzufügen, verlangsamt dies Ihren Geschwindigkeitswert

Wie wäre es mit TBT? Wenn Sie Google Analytics hinzufügen, verlangsamt dies Ihren Geschwindigkeitswert

Das liegt an ihrer Empfehlung, das Skript vor den Inhalt zu stellen. Wenn Sie es unter den Inhalt legen, sinkt die Punktzahl nicht.

Ich persönlich sehe keine wirklichen Vorteile darin, das Skript an die erste Stelle zu setzen. Wenn das Laden der Seite irgendwie unterbrochen war und HTML irgendwie nicht vollständig geladen und abgebrochen wurde, kann ich es möglicherweise nicht als Treffer zählen, also was auch immer.

Ich arbeite mit nextjs. Ich versuche, die automatische Vervollständigungs-API von Google Place zu verwenden. Und möchte diese Skript-Tag der API einfügen? Wo soll ich diese Skript-Tags einfügen?

_app.js

`` `js
ReactGA aus "react-ga" importieren;

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);
    });
}

Das ist urkomisch. Nein, eigentlich ist das traurig. Ich kann es kaum erwarten, bis React, Next, das gesamte Ökosystem stirbt.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen