Next.js: إضافة علامة نص GA؟

تم إنشاؤها على ٣٠ أكتوبر ٢٠١٦  ·  74تعليقات  ·  مصدر: vercel/next.js

مرحبا!

أقوم حاليًا بتحويل موقع الويب الخاص بي إلى مشروع next.js ولا يمكنني معرفة كيفية إضافة علامة النص البرمجي لبرنامج Google Analytics إلى الصفحة. أي أفكار؟

في صحتك،
روبن

التعليق الأكثر فائدة

لا حاجة ل react-ga . استخدم مدير علامات google مع المكون <Head> لإدخال التحليلات. هناك بعض التغييرات الصغيرة في كود مدير علامات google اللازمة لجعله يعمل في nextjs / رد فعل:

<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

ال 74 كومينتر

الخروج <Head>

robinvdvleuten أقترح إنشاء مكون

كما ذكر الأشخاص ، يمكنك استخدام علامة Head أو حل سهل التفاعل مثل https://github.com/react-ga/react-ga

أي نصائح حول كيفية التعامل مع رد فعل ga مع next.js؟

gtramontina يجب أن تعمل. وإلا فأنا أحد المساهمين react-ga لذا يمكنني المساعدة في ذلك

لا حاجة ل react-ga . استخدم مدير علامات google مع المكون <Head> لإدخال التحليلات. هناك بعض التغييرات الصغيرة في كود مدير علامات google اللازمة لجعله يعمل في nextjs / رد فعل:

<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

أود أن أوصي بحل أفضل لتتبع عرض صفحة جانب العميل: المسار التلقائي. راجع https://github.com/MoOx/phenomic/issues/384 لمزيد من المعلومات.

impronunciable سيكون رائعًا أن يكون لديك مثال كما بعد بعض googling ما زلت مرتبكًا 😃 هل يمكن إعادة فتح هذا؟

  • يبدو أن MoOx يشير إلى أن رد فعل ga ليس ضروريًا ، لذا يجب استخدام Google AutoTrack بدلاً من ذلك
  • لكن Autotrack يرشد إلى إنشاء علامة نصية برمز يصل إلى كائن window ، بحيث لا يعمل ذلك من جانب الخادم
  • وعلى أي حال إذا كنت تستخدم مكون تفاعل مثل رد فعل-جا ، فأين يجب وضعه؟ في render ؟ componentWillMount ؟ getInitialProps ؟ إنه ليس واضحًا تمامًا لأنه يفترض نوعًا ما أنك تستخدم جهاز توجيه رد الفعل وتحميل الكود مرة واحدة لجميع الصفحات.

يجب أن يعمل تتبع الصفحة عند عرض الصفحة على الخادم ثم عند الانتقال إلى صفحة أخرى. سيكون من الرائع أن نرى كيف يجب أن يتكامل كل شيء في تطبيق Next النموذجي برأس ، وتخطيط الصفحة ذات الترتيب الأعلى ، وما إلى ذلك.

سيكون من الرائع أيضًا معرفة ما إذا كنت تعتقد أن هناك مجموعة أفضل / أبسط / أقل تعقيدًا / أكثر حداثة من Next.js + Google Analytics Autotrack ...

يمكنني التحقيق في هذا

يوم الثلاثاء ، 17 يناير 2017 ، الساعة 7:59 صباحًا Sébastien Dubois [email protected]
كتب:

impronunciable https://github.com/impronunciable سيكون رائعًا
لديك مثال بعد بعض googling ما زلت مرتبكًا 😃 هل يمكن ذلك
يعاد فتحه؟

  • يبدو أن MoOx https://github.com/MoOx يعني أن رد فعل ga ليس كذلك
    ضروري ، يجب استخدام Google AutoTrack
    https://github.com/googleanalytics/autotrack بدلاً من ذلك
  • لكن Autotrack يرشد إلى إنشاء علامة نصية برمز
    يصل إلى كائن النافذة ، بحيث لا يعمل من جانب الخادم
  • وعلى أي حال إذا كنت تستخدم مكون تفاعل مثل رد فعل-جا ، فأين يجب
    يتم وضعه؟ في تقديم؟ المكونWillMount؟ getInitialProps؟ ليست كذلك
    فائق الوضوح لأنه يفترض نوعًا ما أنك تستخدم جهاز توجيه رد الفعل وتحميل ملف
    رمز مرة واحدة لجميع الصفحات.

يجب أن يعمل تتبع الصفحة عندما يتم عرض الصفحة على الخادم و
ثم عند الانتقال إلى صفحة أخرى. سيكون من الرائع أن نرى كيف
يجب أن يتكامل كل شيء في تطبيق Next النموذجي مع صفحة رئيسية
تخطيط HOC ، إلخ.

سيكون من الرائع أيضًا معرفة ما إذا كنت تعتقد أن هناك أفضل / أبسط / أقل
تركيبة مرهقة / أكثر حداثة من Next.js + Google
تحليلات التتبع التلقائي ...

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/zeit/next.js/issues/160#issuecomment-273108099 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AAKHp9-2bfLXj2hMGlNlkqUSRqEL7R2Cks5rTJ8kgaJpZM4KkXxa
.

متأكد تمامًا من أن autotrack أكثر من كافٍ ، حيث يتم حقنه فقط من جانب العميل - لا داعي للتفكير في جانب الخادم.

راجع https://github.com/MoOx/react-toulouse/commit/c42045d1001ab813c5d7eae5ab2f4f8c08c0025e للحصول على مثال. إنه لا يستخدم التالي ، لكن أعتقد أنه يجب أن يكون سهل التكيف.

نعم ، لا نريد تتبع عمليات عرض الخادم ، نظرًا لأنه سيؤدي إلى تعتيم أشياء مثل الموقع.

لا ، لا تفعل ذلك لأنه سيتم التعامل معها من قبل العميل: ضع في اعتبارك أن الصفحة يطلبها العميل وسيتم عرضها في متصفح العميل :)

حسنًا ، لم أكن أدرك أن الكود يجب ألا يعمل من جانب الخادم. لذلك استخدمت autotrack على النحو الموصى به من قبل https://github.com/relatenow/relate/commit/50dc3f317eb3efa045d5bbe40d1a1a1ad1116458

فقط لم أؤكد بعد ما إذا كان يحسب مشاهدات الصفحة بشكل صحيح ، هذا جديد بالنسبة لي 😬 😄

يمكنك استخدام طريقة العرض "في الوقت الفعلي" لتصحيح أخطاء GA بسهولة.

MoOx نعم حسنًا ، هذا ما يزعجني ، لا أرى أي شيء في لوحة الوقت الفعلي عندما أزور https://relate.now.sh بالتوازي في علامة تبويب أخرى (0 مستخدم نشط)

ما زلت لا أحصل على هذا ... لا أحصل على أي بيانات مع الكود الذي كتبته.

يبدو أن جميع الأمثلة التي أراها تتطلب <script href="https://www.google-analytics.com/analytics.js" async /> ولكن لا يبدو أن الأشياء الموجودة في الرأس يتم تنفيذها في العميل؟ (لا تتم طباعة console.log الخاص بي في وحدة تحكم المتصفح ...)

مثال لا يزال موضع تقدير كبير 🙂

آه ، لقد نجحت في العمل من خلال التبديل إلى رد فعل-جا 😄

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

screen shot 2017-01-18 at 14 01 28

ماذا فعلت لتشغيلها؟ كنت أحاول استدعاء وظيفة مشاهدة الصفحة على componentDidMount .

فشل تطبيق الإنتاج GA Check .

luandro لا تتذكر التفاصيل ، ولكن يمكنك إلقاء نظرة على الالتزام الذي ربطته أعلاه إذا كان يساعدك

فعلت وجربتها. فعلت نفس الشيء مثلك ، واستدعت configAnalytics في الأعلى ، ومشاهدة الصفحة على componentWillMount ، لكن لا تزال تظهر سلبية في GA Check .

في التعليمات البرمجية الخاصة بك ، لا يبدو أنك قمت بالفعل بالاتصال بالصفحة في أي مكان ، أليس كذلك؟

luandro ببساطة أضف ga(‘set’, ‘page’, window.location.pathname); ga(‘send’, ‘pageview’); لتغيير عنوان url لحدث مشاهدة الصفحة.

ربما هناك المزيد من طريقة "next.js" للقيام بذلك ، لكن البرامج النصية التي تعمل على WRT على الصفحة وجدت أنه إذا قمت بإنشاء مكون Script مثل هذا:

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

ثم يمكنني أن أفعل هذا الذي نجح معي:

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

التحذير هو أنه يجب عليك إرفاق كل شيء في وظيفة.

هل من الممكن تتبع مشاهدات الصفحة الفردية بدون استدعاء ga صراحة ("إرسال" ، "مشاهدة الصفحة") في كل صفحة. إذا كان علينا فعل ذلك تمامًا ، فأين نستدعيه من التأكد من أنه تم تحميل ga؟

هل من الممكن الارتباط بأحداث تغيير المسار بطريقة ما لتسجيل مشاهدات الصفحة؟

karthikiyengar أنا أستخدم react-ga كما اقترحه الآخرون أعلاه وأقوم بتسجيل مشاهدات الصفحة على componentDidMount من كل صفحة.

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 هل من الشائع استخدام initGA لكل مكون من مكونات الصفحة؟

rongierlach أنا Layout الذي يستدعي الأساليب initialize و pageview على ReactGA ضمن componentDidMount() .

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

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

هذه هي أنظف طريقة قمت بها حتى الآن كما لو كانت الصفحة معروضة بالخادم ، فهي بحاجة إلى التهيئة. أنا متأكد من أن هناك خطافًا يمكنه تجاوز التهيئة إذا تم تقديم العميل.

notrab هل من المحتمل أن تفوتك العروض الضحلة؟ سيتم نقل تطبيقك فقط وقد لا يتم إعادة تحميل مكون التخطيط الخاص بك. هذا ما يجب أن أمسك بهؤلاء.

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

محاولة الحصول على هذا للعمل ، ولكن لا يوجد استجابة من Google Analytics. هذا هو الكود الخاص بي في 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

وصفحة الفهرس الخاصة بي:

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

مع رمز UA الذي تم استبداله بالكود الفعلي ، بالطبع.

filostrato كيف

انتهى الأمر exogenesys بوضع هذا في 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

وقمت بتغيير Layout.js لتوسيع 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>
    )
  }
}

لم أجد طريقة لجعله يعمل في مكون يستخدم getInitialProps ، لكن بما أن Layout.js لم يعمل بشكل جيد ؛ لست متأكدًا مما أفعله إذا كنت أرغب في الحصول على إحصائيات أكثر تفصيلاً ، لكنني سأعبر هذا الجسر عندما آتي إليه.

filostrato هذا فعلها. شكرا جزيلا. :)

مرحبا شباب

لقد تعاملت للتو مع تنفيذ GA على موقعي أيضًا وهذا ما توصلت إليه.

أولاً ، استخدمت الحل من notrab الذي بدا نظيفًا ومباشرًا:

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

  render() {
    …
  }
}

ومع ذلك ، لاحظت:

  • componentDidMount عندما قمت بالتبديل بين الصفحات من أنواع مختلفة ، لذلك تم استدعاء الوظيفة initialize عدة مرات
  • componentDidMount _ فقط_ عندما قمت بالتبديل بين صفحات من أنواع مختلفة ، لذلك تم استدعاء وظيفة pageview عندها فقط => لديّ نوع الصفحة video على موقع الويب الخاص بي ورأيت طريقة عرض GA Live التي تم فيها تتبع صفحة الفيديو الأولية فقط أثناء التبديل بين صفحات الفيديو المختلفة

لقد قمت بإنشاء مكون عالي المستوى لمعالجة هاتين المشكلتين. لأول مرة استخدمت حل 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} />
      );
    }
  }
);

وفي مكون <Layout> / <PageWrapper> / <PageScaffold> أو أيًا كان ما تسميه:

import GaWrapper from './ga-wrapper';

const PageScaffold = () => (…);

export default GaWrapper(PageScaffold);

ربما يساعد ذلك أي شخص.

لا أحب استدعاء Router.router.events.… ، لأن هذا ليس جزءًا من واجهة برمجة التطبيقات الموثقة. ومع ذلك ، عندما حاولت الاتصال بـ Router.onRouteChangeComplete والتي يجب أن تكون الطريقة الصحيحة ، حصلت على خطأ في ReferenceError لأن onRouteChangeComplete كان undefined . ربما تكون الوثائق قديمة؟

لقد نجح هذا معي في موقع next.js. وتجاوز الخطأ "لم يتم تعريف النافذة" الذي كنت أواجهه مع التنفيذ المعتاد لـ response-ga.

osartun حل يعمل بالنسبة لي. شكرا لك! 👍

بفضل كودosartun ، تمكنت من التوصل إلى الحل التالي لإطلاق أحداث pageview باستخدام gtag الجديد من Google (الذي يحل محل البرامج النصية للتحليلات العالمية):

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 / أيا كان اسم مشروعك:

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

بالنسبة لأي شخص يأتي متأخرًا إلى الحفلة ، فإن السبب وراء عدم نجاح حل componentDidMount . يبدو أن تحديدها خارج المكون يحل المشكلة:

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

trezy عند استخدام gtag ، يبدو أنه ليست هناك حاجة إلى import ReactGA from 'react-ga' .

لقد استخدمت مثالك <script dangerouslySetInnerHtml={...} /> وأضفت للتو هذا السطر إلى الحقن:

window.gaTrackingId = '${gaTrackingId}';

بعد ذلك ، بدأت هذه الحيلة خفيفة الوزن في العمل:

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

لم يعد يتم جلب analytics.js كبير جدًا من

نظرًا لأن هذا ليس واضحًا ، سيكون من الجيد أن يكون لديك مثال في الريبو.

أو مستودع تحليلات جوجل التالي 🕵️

prichodko شكرا جزيلا لتجميع هذا المثال !!

وجدت lib لطيفة جدًا ، تمت إضافتها إلى ملف التخطيط الرئيسي في componentDidMount () ويبدو أنه يعمل بشكل صحيح. موثقة جيدا ، لا صخب

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

andylacko في الواقع ، لقد قمت https://github.com/Vadorequest/react-gtm

ما عليك سوى إضافة الحل الخاص بي إلى هذا هنا في حال قد يكون مفيدًا لشخص ما لاحقًا.

لقد استخدمت رد فعل- ga ولكن نفس المنطق يجب أن يعمل مع أدوات ga الأخرى.

يتم تشغيل getInitialProps _app.js على جانب العميل عندما ينقر المستخدم على مسار جديد. (سيتم تشغيله لأول مرة على جانب الخادم).

componentDidMount من _app.js جانب العميل فقط.

لذلك في _app.js ، أضفت الأسطر القليلة التالية من التعليمات البرمجية


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

عندما يتم عرض الصفحة في الخادم ، لن يحدث شيء في getInitialProps لأنني قمت بلف كود GA في typeof(window) === "object" .

من جانب العميل ، لن يتم تشغيل getInitialProps للمرة الأولى حيث يتم عرض كل شيء على الخادم. يتم إعداد GA داخل componentDidMount من جانب العميل.

ستؤدي تغييرات المسار اللاحقة (حتى لنفس المسار) إلى تشغيل getInitialProps جانب العميل وسيتم تشغيل حدث ga.

ما عليك سوى إضافة الحل الخاص بي إلى هذا هنا في حال قد يكون مفيدًا لشخص ما لاحقًا.

لقد استخدمت رد فعل- ga ولكن نفس المنطق يجب أن يعمل مع أدوات ga الأخرى.

يتم تشغيل getInitialProps _app.js على جانب العميل عندما ينقر المستخدم على مسار جديد. (سيتم تشغيله لأول مرة على جانب الخادم).

componentDidMount من _app.js جانب العميل فقط.

لذلك في _app.js ، أضفت الأسطر القليلة التالية من التعليمات البرمجية


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

عندما يتم عرض الصفحة في الخادم ، لن يحدث شيء في getInitialProps لأنني قمت بلف كود GA في typeof(window) === "object" .

من جانب العميل ، لن يتم تشغيل getInitialProps للمرة الأولى حيث يتم عرض كل شيء على الخادم. يتم إعداد GA داخل componentDidMount من جانب العميل.

ستؤدي تغييرات المسار اللاحقة (حتى لنفس المسار) إلى تشغيل getInitialProps جانب العميل وسيتم تشغيل حدث ga.

يا ويل. هل تضمين ReactGA في webpack الخاص بك (حيث يتم تشغيله بجانب العميل) له تأثير كبير على حجم الإنشاء لديك؟

ChrisEdson https://github.com/react-ga/react-ga المكتبة بأكملها 161 كيلو بايت مضغوط.

همم. هذا ضخم للغاية لنكون صادقين!

في الخميس ، 28 فبراير 2019 الساعة 19:01 ، كتب William Li [email protected] :

ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga المكتبة بأكملها مضغوطة 161 كيلو بايت.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/zeit/next.js/issues/160#issuecomment-468395136 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa
.

هذا هو الرقم المدرج في GitHub للمكتبة بأكملها.
كيف أتحقق من الحجم الفعلي بمجرد تعبئته في التطبيق؟

مرسل من الايفون الخاص بي

في 1 آذار (مارس) 2019 ، الساعة 15:43 ، كتب Chris Edson [email protected] :

همم. هذا ضخم للغاية لنكون صادقين!

في الخميس ، 28 فبراير 2019 الساعة 19:01 ، كتب William Li [email protected] :

ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga المكتبة بأكملها مضغوطة 161 كيلو بايت.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/zeit/next.js/issues/160#issuecomment-468395136 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa
.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على GitHub ، أو قم بكتم صوت الموضوع.

لذا فإن النص المصغر هو 15 كيلوبايت. هذا صغير جدًا.

سأقوم بتحليل حزمة الويب الخاصة بي وسأبلغ مرة أخرى عن مقدار ما يضيفه عمليًا.

ضمن حجم حزمة إجمالي يبلغ 500 كيلو بايت تقريبًا ، تضيف ReactGA حوالي 27 كيلو بايت. صغيرة جدًا في المخطط الكبير للأشياء.

ما عليك سوى إضافة الحل الخاص بي إلى هذا هنا في حال قد يكون مفيدًا لشخص ما لاحقًا.

لقد استخدمت رد فعل- ga ولكن نفس المنطق يجب أن يعمل مع أدوات ga الأخرى.

يتم تشغيل getInitialProps _app.js على جانب العميل عندما ينقر المستخدم على مسار جديد. (سيتم تشغيله لأول مرة على جانب الخادم).

componentDidMount من _app.js جانب العميل فقط.

لذلك في _app.js ، أضفت الأسطر القليلة التالية من التعليمات البرمجية


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

عندما يتم عرض الصفحة في الخادم ، لن يحدث شيء في getInitialProps لأنني قمت بلف كود GA في typeof(window) === "object" .

من جانب العميل ، لن يتم تشغيل getInitialProps للمرة الأولى حيث يتم عرض كل شيء على الخادم. يتم إعداد GA داخل componentDidMount من جانب العميل.

ستؤدي تغييرات المسار اللاحقة (حتى لنفس المسار) إلى تشغيل getInitialProps جانب العميل وسيتم تشغيل حدث ga.

هناك مشكلة تنشأ إذا كنت تستخدم NextJS 9 وهي أن هذا مع تعطيل العرض المسبق التلقائي. أتساءل عما إذا كان هناك مكان أفضل لوضع ReactGA.pageview(ctx.asPath); ، وإزالته من getInitialProps يعني أنه يمكننا إزالة getInitialProps وليس فرض العرض المسبق التلقائي على إلغاء الاشتراك كما هو موضح هنا: https : //err.sh/next.js/opt-out-automatic-prerendering.

تحديث: لقد عثرت على مثال with-google-analytics (https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics) واقترضت القليل حول: Router.events.on('routeChangeComplete', url => ReactGA.pageview(url)) أحتاج إلى اختبار هذا للتأكد من صحة عنوان url ولكن يبدو أنه بالطريقة الصحيحة. لقد أزلت طريقة getInitialProps وأضفتها فوق إعلان الفئة.

GodOfGrandeur هذا يبدو واعدًا ، سأحاول في المنتج. لم تحصل على الإصدار المذكور أعلاه يعمل أو يبدو هكذا https://medium.com/@austintoddj/using -google-analytics-with-next-js-423ea2d16a98 يبدو أن إضافة الكود الخاص بك في _app.js يبدو أنه يتم تشغيله في كل مكان حسب الحاجة وأحب أيضًا أنه لا يتم تشغيله على الخادم (لن يحدث ذلك على الرغم من أنها مشكلة).

لا حاجة لأي طرف ثالث ، إذا كنت تستخدم gtag ، فاستخدم الكود التالي الذي أنشأته: -

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

خيار آخر هو استخدام useEffect() . لقد قمت بهذا في ملف 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,
    })
  }
})

وفي <Head> :

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

reinink فقط أريد أن أذكر أنك قد ترغب في تمرير مصفوفة فارغة كعنصر ثانٍ إلى useEffect بحيث يتم تشغيل الوظيفة مرة واحدة فقط بعد التصيير الأولي.

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

التوسيع على حل reinink s ، إليك

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

لم يتم اختباره على نطاق واسع ولكنه يعمل ويصبح زائرًا حقيقيًا يعمل محليًا. :)

لقد وجدت هذا الدليل - هل هذا نهج موصى به (يستخدم رد فعل ga)؟

أود أن أقول إن الطريقة الموصى بها هي استخدام هذا المثال الرسمي:

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

تم نشره بالفعل هنا. في بعض الأحيان ، أتمنى أن تكون مشكلات github أشبه بميزة stackoverflow ، حيث يتم قبول بعض الإجابات وتسليط الضوء عليها ، مباشرة بعد السؤال (عندما يكون هناك عدد كبير جدًا من الرسائل والرموز التعبيرية غير كافية. أحد الخيارات هو تقييد التعليق على هذه المشاركة ، حتى ينشئ الأشخاص مشكلة جديدة بدلاً من ذلك. وأثناء الإنشاء ، سيجدون أن مشكلة مماثلة قد تم إنشاؤها بالفعل (بفضل ميزة "مشكلات مماثلة") ، ولديها إجابة (ولكن لا تزال الإجابة باستخدام الرموز التعبيرية مفقودة في مكان ما في منتصف التاريخ الطويل ، لذا فهي ليس من الملائم جدًا العثور على إجابات على جيثب).

تم نشره بالفعل هنا. في بعض الأحيان ، أرغب في أن تكون مشكلات github أشبه ببرنامج stackoverflow ، حيث يتم قبول بعض الإجابات وإبرازها ، مباشرة بعد السؤال (عندما يكون هناك عدد كبير جدًا من الرسائل والرموز التعبيرية غير كافية ...

يقوم Github بوضع نماذج أولية لهذا الأمر في علامة تبويب المناقشات في الريبو.

Screenshot 2020-04-08 at 16 59 58

janbaykara واو ، حقا؟ نفكر جميعًا بنفس الطريقة :) آمل أن يجدوا طريقة بطريقة ما لترجمة قضية ما إلى مناقشة ، أو سيكون الأمر نفسه (إذا تم دمج الوظائف في المشكلات ، وستصبح جميع المناقشات الحالية مشكلات). لكن شكرا على الرد!

@ 3lonious لقد تخلصت شخصيًا من Google Analytics ، حيث إنه لا يعمل بشكل جيد مع SPA بشكل عام. (تجربة سيئة حقًا ، خاصة مع SSR + CSR والأحداث المزدوجة التي يصعب تعقبها)

بخصوص Next.js ، تحقق من https://github.com/UnlyEd/next-right-now/blob/v2-mst-aptd-gcms-lcz-sty/src/components/pageLayouts/Head.tsx (باستخدام next/Head ) ، هكذا أقوم بتضمين علامات البرنامج النصي في تطبيقاتي.

لا تتردد في إلقاء نظرة على NRN https://unlyed.github.io/next-right-now ، من المفترض أن تكون مثالًا جيدًا على "كيفية تنفيذ X" باستخدام Next.js ويجب أن يوفر لك بعض الصداع.

لست متأكدًا من أنني حصلت عليه ، لا أرى أي علامات نصية في هذا الملف؟

هذا أيضًا حل ناجح. لم أختبرها على نطاق واسع ، لذا يرجى القيام بذلك بنفسك.

في pages/_document.js ، أضف هذا إلى <Head> . راجع المستندات حول كيفية تجاوز ملف المستند .

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

تقوم بإبلاغ حركة المرور إلى حساب GA الخاص بي على الأقل.

تعمل علامات
الحل أعلاه يعمل أيضًا ، من التجربة. (هذه هي الطريقة التي اعتدت أن أجعل بها GA تعمل)

حسنا شكرا يا شباب. سأحاول وأعود إليك

حسنًا ، أعتقد أنني حصلت عليه للعمل

شكرا انطون. حسنًا ، لدي واحدة جديدة لك هاها

لدي تطبيق دردشة أستخدمه لخدمة العملاء ولكن علامة البرنامج النصي هذه لا تعمل أيضًا؟ أيه أفكار؟

هل تطلب مني إضافة هذه العلامة الثانية في النص؟ ماذا تفعل مع ذلك؟
Screen Shot 2020-06-19 at 6 48 22 AM

ماذا عن TBT؟ إذا قمت بإضافة تحليلات جوجل ، فسيؤدي ذلك إلى إبطاء درجة سرعتك

ماذا عن TBT؟ إذا قمت بإضافة تحليلات جوجل ، فسيؤدي ذلك إلى إبطاء درجة سرعتك

هذا بسبب توصيتهم بوضع النص قبل المحتوى. إذا قمت بوضعه تحت المحتوى ، فلن تنخفض النتيجة.

أنا شخصياً لا أرى فوائد حقيقية لوضع النص أولاً. إذا كان تحميل الصفحة معطلاً بطريقة ما ، ولم يتم تحميل HTML بالكامل بطريقة ما وتم إحباطه ، فقد لا أحسبه على أنه نتيجة ، لذا أيا كان.

أنا أعمل مع nextjs. أحاول استخدام رد فعل google place auto Complete API. ويريد إدراج علامة البرنامج النصي من API؟ أين يجب أن أدخل علامة البرنامج النصي تلك ؟؟

_app.js

شبيبة
استيراد ReactGA من "رد فعل- 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);
    });
}

هذا مضحك جدا. لا ، هذا محزن في الواقع. لا يمكن أن تنتظر رياكت ، التالي ، النظام البيئي بأكمله يموت.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات