Next.js: рдЬреАрдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдЬреЛрдбрд╝рдирд╛?

рдХреЛ рдирд┐рд░реНрдорд┐рдд 30 рдЕрдХреНрддреВре░ 2016  ┬╖  74рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: vercel/next.js

рдирдорд╕реНрддреЗ!

рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрдкрдиреА рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреЛ рдиреЗрдХреНрд╕реНрдЯ.рдЬреЗрдПрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддрд╛ рдХрд┐ рдкреЗрдЬ рдкрд░ Google Analytics рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдХреИрд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПред рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?

рдЪреАрдпрд░реНрд╕,
рд░реЛрдмрд┐рди

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

react-ga рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╡рд┐рд╢реНрд▓реЗрд╖рд┐рдХреА рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП <Head> рдШрдЯрдХ рдХреЗ рд╕рд╛рде Google рдЯреИрдЧ рдкреНрд░рдмрдВрдзрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЕрдЧрд▓реА рдмрд╛рд░ jj / рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Google рдЯреИрдЧ рдкреНрд░рдмрдВрдзрдХ рдХреЛрдб рдореЗрдВ рдХреБрдЫ рдЫреЛрдЯреЗ рдмрджрд▓рд╛рд╡ рдЖрд╡рд╢реНрдпрдХ рд╣реИрдВ:

<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 рдореИрдВ рдПрдХ GoogleTagManager рдШрдЯрдХ рдмрдирд╛рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рдХрд░реВрдВрдЧрд╛ ред

рдЬреИрд╕рд╛ рдХрд┐ рд▓реЛрдЧреЛрдВ рдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдЖрдк Head рдЯреИрдЧ рдпрд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЕрдиреБрдХреВрд▓ рд╕рдорд╛рдзрд╛рди рдЬреИрд╕реЗ https://github.com/react-ga/react-ga рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдЕрдЧрд▓реЗ-js рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрд╛ рдХрд╛рдо рдХрд░рдиреЗ рдкрд░ рдХреЛрдИ рд╕реБрдЭрд╛рд╡?

@gtramontina рдХреЛ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдиреНрдпрдерд╛ рдореИрдВ react-ga рдпреЛрдЧрджрд╛рдирдХрд░реНрддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реВрдВ рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ

react-ga рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╡рд┐рд╢реНрд▓реЗрд╖рд┐рдХреА рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП <Head> рдШрдЯрдХ рдХреЗ рд╕рд╛рде Google рдЯреИрдЧ рдкреНрд░рдмрдВрдзрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЕрдЧрд▓реА рдмрд╛рд░ jj / рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Google рдЯреИрдЧ рдкреНрд░рдмрдВрдзрдХ рдХреЛрдб рдореЗрдВ рдХреБрдЫ рдЫреЛрдЯреЗ рдмрджрд▓рд╛рд╡ рдЖрд╡рд╢реНрдпрдХ рд╣реИрдВ:

<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 рдпрд╣ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдХреБрдЫ

  • @MoOx рдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп Google AutoTrack рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
  • рд▓реЗрдХрд┐рди рдСрдЯреЛрдЯреНрд░реИрдХ рдиреЗ рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдмрдирд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрджреЗрд╢ рджрд┐рдпрд╛, рдЬреЛ window рдСрдмреНрдЬреЗрдХреНрдЯ рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИ, рддрд╛рдХрд┐ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рди рд╣реЛ
  • рдФрд░ рд╡реИрд╕реЗ рднреА рдпрджрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрд╛ рдЬреИрд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдХрд╣рд╛рдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП? рдПрдХ render ? componentWillMount ? getInitialProps ? рдпрд╣ рд╕реБрдкрд░ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХрд╛ рд╣реИ рдХрд┐ рдЖрдк рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд╛рдЙрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕рднреА рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдХреЛрдб рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВред

рдЬрдм рдкреГрд╖реНрда рд╕рд░реНрд╡рд░-рд░реЗрдВрдбрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рддрдм рдХрд┐рд╕реА рдЕрдиреНрдп рдкреГрд╖реНрда рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рддреЗ рд╕рдордп рдкреГрд╖реНрда рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЛ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рджреЗрдЦрдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХреИрд╕реЗ рдПрдХ рд╣реЗрдб, рдПрдХ рдкреЗрдЬ рд▓реЗрдЖрдЙрдЯ рдПрдЪрдУрд╕реА, рдЖрджрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рдареЗрда рдЕрдЧрд▓рд╛ рдРрдк рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдпрд╣ рдЬрд╛рдирдХрд░ рднреА рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ Next.js + Google Analytics рдСрдЯреЛрдЯреНрд░реИрдХ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмреЗрд╣рддрд░ / рд╕рд░рд▓ / рдХрдо рдмреЛрдЭрд┐рд▓ / рдЕрдзрд┐рдХ рдЕрддреНрдпрд╛рдзреБрдирд┐рдХ рд╕рдВрдпреЛрдЬрди рд╣реИ ...

рдореИрдВ рдЗрд╕рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ

Tue рдкрд░, 17 рдЬрдирд╡рд░реА, 2017, 7:59 AM S├йbastien Dubois рд╕реВрдЪрдирд╛рдПрдВ @github.com
рд▓рд┐рдЦрд╛ рдерд╛:

@impronunciable https://github.com/impronunciable рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХреБрдЫ googling рдХреЗ рдмрд╛рдж рдореИрдВ рдЕрднреА рднреА рдЙрд▓рдЭрди рдореЗрдВ рд╣реВрдБ some рдпрд╣ рдХрд░ рд╕рдХрддрд╛ рд╣реИ
рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓ рджрд┐рдпрд╛ рдЬрд╛рдП?

  • @MoOx https://github.com/MoOx рдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЬреА рдирд╣реАрдВ рд╣реИ
    рдЖрд╡рд╢реНрдпрдХ, Google AutoTrack рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
    рдЗрд╕рдХреЗ рдмрдЬрд╛рдп https://github.com/googleanalytics/autotrack
  • рд▓реЗрдХрд┐рди рдСрдЯреЛрдЯреНрд░рд╛рдХ рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдмрдирд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрджреЗрд╢ рджреЗрддрд╛ рд╣реИ
    рд╡рд┐рдВрдбреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рддрд╛ рд╣реИ, рддрд╛рдХрд┐ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдХрд╛рдо рди рдХрд░реЗ
  • рдФрд░ рд╡реИрд╕реЗ рднреА рдЕрдЧрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрд╛ рдЬреИрд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдХрд╣рд╛рдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
    рдЗрд╕реЗ рд░рдЦрд╛ рдЬрд╛рдП? рдПрдХ рд░реЗрдВрдбрд░ рдореЗрдВ? componentWillMount? getInitialProps? рдпрд╣
    рд╕реБрдкрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХрд╛ рд╣реИ рдХрд┐ рдЖрдк рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд╛рдЙрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ
    рд╕рднреА рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдХреЛрдбред

рдкреЗрдЬ рдЯреНрд░реИрдХрд┐рдВрдЧ рд╕рд░реНрд╡рд░-рд░реЗрдВрдбрд░ рдФрд░ рдЬрдм рджреЛрдиреЛрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
рддрдм рдЬрдм рджреВрд╕рд░реЗ рдкреГрд╖реНрда рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рдирд╛ рд╣реЛред рдпрд╣ рджреЗрдЦрдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ
рдкреВрд░реА рдмрд╛рдд рдПрдХ рд╣реЗрдб, рдПрдХ рдкреЗрдЬ рдХреЗ рд╕рд╛рде рдПрдХ рдареЗрда рдиреЗрдХреНрд╕реНрдЯ рдРрдк рдореЗрдВ рдЗрдВрдЯреАрдЧреНрд░реЗрдЯ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП
рд▓реЗрдЖрдЙрдЯ HOC, рдЖрджрд┐ред

рдпрд╣ рдЬрд╛рдирдирд╛ рднреА рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмреЗрд╣рддрд░ / рд╕рд░рд▓ / рдХрдо рд╣реИ
Next.js + Google рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмреЛрдЭрд┐рд▓ / рдЕрдзрд┐рдХ рдЕрддреНрдпрд╛рдзреБрдирд┐рдХ рд╕рдВрдпреЛрдЬрди
Analytics рдСрдЯреЛрдЯреНрд░реИрдХ ...

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рдЙрддреНрддрд░ рд╕реАрдзреЗ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/zeit/next.js/issues/160#issuecomment-273108099 , рдпрд╛ рдореНрдпреВрдЯ
рд╕реВрддреНрд░
https://github.com/notifications/unsubscribe-auth/AAKHp9-2bfLXj2hMGlNlkqUSRqEL7R2Cks5rTJ8kgaJpZM4KkXxa
ред

рдмрд╣реБрдд рдпрдХреАрди рд╣реИ рдХрд┐ рдСрдЯреЛрдЯреНрд░реИрдХ рдкрд░реНрдпрд╛рдкреНрдд рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рдХреЗрд╡рд▓ рдЧреНрд░рд╛рд╣рдХ рдкрдХреНрд╖ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП https://github.com/MoOx/react-toulouse/commit/c42045d1001ab813c5d7eae5ab2f4f8c08c0025e рджреЗрдЦреЗрдВред рдпрд╣ рдЖрдЧреЗ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╣рд╛рдБ, рд╣рдо рд╕рд░реНрд╡рд░ рд░реЗрдВрдбрд░ рдХреЛ рдЯреНрд░реИрдХ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕реНрдерд╛рди рдЬреИрд╕реА рдЪреАрдЬреЛрдВ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░реЗрдЧрд╛ред

рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдЗрд╕реЗ рдЧреНрд░рд╛рд╣рдХ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ: рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдЧреНрд░рд╛рд╣рдХ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдкреГрд╖реНрда рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЧреНрд░рд╛рд╣рдХ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред :)

рдареАрдХ рд╣реИ рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рдирд╣реАрдВ рд╣реБрдЖ рдХрд┐ рдХреЛрдб рдХреЛ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдирд╣реАрдВ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ @MoOx рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд╢рдВрд╕рд┐рдд рдСрдЯреЛрдЯреНрд░реИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП: https://github.com/relatenow/relate/commit/50dc3f317eb3efa045d5bbe40d1a1ad1116458

рдЕрднреА рддрдХ рдЗрд╕рдХреА рдкреБрд╖реНрдЯрд┐ рдирд╣реАрдВ рдХреА рдЧрдИ рд╣реИ рдпрджрд┐ рдпрд╣ рдкреГрд╖реНрда рдХреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЧрд┐рдирддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдирдпрд╛ рд╣реИ it it

рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдЬреАрдП рдХреЛ рдбреАрдмрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП "рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп" рджреГрд╢реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

@рдореЛрдХреНрд╕ рд╣рд╛рдБ, рдпрд╣ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╣реИ рдЬреЛ рдореБрдЭреЗ рдкрд░реЗрд╢рд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрдм рдореИрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рдЯреИрдм рдореЗрдВ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ https://relate.now.sh рдкрд░ рдЬрд╛рддрд╛ рд╣реВрдВ рддреЛ рдореБрдЭреЗ рд░рд┐рдпрд▓рдЯрд╛рдЗрдо рдкреИрдирд▓ рдореЗрдВ рдХреБрдЫ рднреА рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ (0 рд╕рдХреНрд░рд┐рдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛)

рдореБрдЭреЗ рдЕрднреА рднреА рдпрд╣ рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИ ... рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рдХреЛрдб рдХреЗ рд╕рд╛рде рдореБрдЭреЗ рдХреЛрдИ рдбреЗрдЯрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИред

рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рджреЗрдЦреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ <script href="https://www.google-analytics.com/analytics.js" async /> рдЖрд╡рд╢реНрдпрдХрддрд╛ рд▓рдЧрддреА рд╣реИ, рд▓реЗрдХрд┐рди рд╣реЗрдб рдореЗрдВ рдЪреАрдЬреЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВ? (рдореЗрд░рд╛ рдХрдВрд╕реЛрд▓.рд▓реЙрдЧ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдореБрджреНрд░рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ ...)

рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЕрднреА рднреА рдмрд╣реБрдд рд╕рд░рд╛рд╣рдирд╛ рдХреА рдЬрд╛рдПрдЧреА very

рдЖрд╣, рдпрд╣ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрд╛ it рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдХреЗ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ

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

screen shot 2017-01-18 at 14 01 28

рддреБрдордиреЗ рдЗрд╕рд╕реЗ рдХрд╛рдо рдХреИрд╕реЗ рд▓рд┐рдпрд╛? рдореИрдВ рдПрдХ рдкреЗрдЬрд╡реНрдпреВ рдлрдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрдВрдкреЛрдиреЗрдВрдЯрдбрд┐рдорд╛рдЙрдВрдЯ ред

рдЙрддреНрдкрд╛рджрди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬреАрдП рдЪреЗрдХ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИред

@luandro рд╡рд┐рд╡рд░рдг рдпрд╛рдж рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдорджрдж рдХрд░рддрд╛ рд╣реИ рддреЛ рдЖрдк рдКрдкрд░ рджрд┐рдП рдЧрдП рд▓рд┐рдВрдХ рдкрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ

рдореИрдВрдиреЗ рдХрд┐рдпрд╛ рдФрд░ рдХреЛрд╢рд┐рд╢ рдХреАред рдореИрдВрдиреЗ рдЖрдкрдХреЗ рдЬреИрд╕рд╛ рд╣реА рдХрд┐рдпрд╛, рд╢реАрд░реНрд╖ рдкрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░рдПрдирд╛рд▓рд┐рдЯрд┐рдХреНрд╕ рдХреЛ рдХреЙрд▓ componentWillMount рдкрд░ рдкреЗрдЬрд╡реНрдпреВ , рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдЬреАрдП рдЪреЗрдХ рдкрд░ рдирдХрд╛рд░рд╛рддреНрдордХ рдорд┐рд▓рддрд╛ рд╣реИред

рдЖрдкрдХреЗ рдХреЛрдб рдореЗрдВ рдРрд╕рд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╣реАрдВ рднреА рдкреЗрдЬ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВ, рдХреНрдпрд╛ рдЖрдкрдиреЗ?

@luandro рдмрд╕ рдкреЗрдЬрд╡реНрдпреВ рдЗрд╡реЗрдВрдЯ рдХреЗ url рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП ga(тАШsetтАЩ, тАШpageтАЩ, window.location.pathname); ga(тАШsendтАЩ, тАШpageviewтАЩ); рдЬреЛрдбрд╝реЗрдВред

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ 'рдиреЗрдХреНрд╕реНрдЯ' рдЬреЗрдПрд╕ рддрд░реАрдХрд╛ рд╣реЛ рд▓реЗрдХрд┐рди рдкреЗрдЬ рдкрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦрдиреЗ рдореЗрдВ 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>
    )
  }
}

рдЪреЗрддрд╛рд╡рдиреА рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдм рдХреБрдЫ рд╕рдВрд▓рдЧреНрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдХреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдкреГрд╖реНрда рдкрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЧрд╛ ('рднреЗрдЬреЗрдВ', 'рдкреЗрдЬрд╡реНрдпреВ') рдХреЛ рдмреБрд▓рд╛рдП рдмрд┐рдирд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреЗрдЬрд╡реНрдпреВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдЕрдЧрд░ рд╣рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдпрд╣ рдХрд░рдирд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдХрд╣рд╛рдБ рд╕реЗ рд▓рд╛рддреЗ рд╣реИрдВ рдХрд┐ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ?

рдХреНрдпрд╛ рдкреГрд╖реНрдарджреГрд╢реНрдпреЛрдВ рдХреЛ рд▓реЙрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рд░реНрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдмрд╛рдБрдзрдирд╛ рд╕рдВрднрд╡ рд╣реИ?

@karthiyiyengar рдореИрдВ 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>
    )
}

рдпрд╣ рд╕рдмрд╕реЗ рд╕рд╛рдл рддрд░реАрдХрд╛ рд╣реИ рдЬреЛ рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдХрд┐рдпрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдкреЗрдЬ рд╕рд░реНрд╡рд░ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕реЗ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рдПрдХ рд╣реБрдХ рд╣реИ рдЬреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЕрдЧрд░ рд╡рд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

@ рдирд╣реАрдВ рдЖрдк рд╕рдВрднрд╛рд╡рд┐рдд рдЙрдерд▓реЗ рд░реЗрдВрдбрд░ рд▓рд╛рдкрддрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ? рд╡реЗ рдЖрдкрдХрд╛ рдРрдк рдХреЗрд╡рд▓ рд╕рдВрдХреНрд░рдордг рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЖрдкрдХрд╛ рд▓реЗрдЖрдЙрдЯ рдШрдЯрдХ рд░реАрдорд╛рдЙрдВрдЯ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрд╣реА рдкрдХрдбрд╝рдирд╛ рд╣реИред

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

рдпреВрдП рдХреЛрдб рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдмрд┐рд▓реНрдХреБрд▓ред

@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 рдиреЗ рдРрд╕рд╛ рдХрд┐рдпрд╛ред рдмрд╣реБрдд рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред :)

рд╣реЗ рд▓реЛрдЧреЛрдВ

рдореИрдВрдиреЗ рдЕрднреА рдЕрдкрдиреА рд╕рд╛рдЗрдЯ рдкрд░ рдЬреАрдП рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рдирд┐рдкрдЯрд╛ рд╣реИ рдФрд░ рдпрд╣реА рдореИрдВ рд╕рд╛рде рдЖрдпрд╛ рд╣реВрдВред

рдкрд╣рд▓реЗ рдореИрдВрдиреЗ @ рдиреЛрдЯ рд╕реЗ рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬреЛ рд╕рд╛рдл рдФрд░ рд╕реАрдзреЗ рдЖрдЧреЗ рд▓рдЧрддрд╛ рдерд╛:

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

  render() {
    тАж
  }
}

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВрдиреЗ рджреЗрдЦрд╛:

  • componentDidMount рддрдм рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдЬрдм рдореИрдВрдиреЗ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреГрд╖реНрдареЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП initialize рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрдИ рдмрд╛рд░ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛
  • componentDidMount _only_ рдХреЛ рддрдм рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрдм рдореИрдВрдиреЗ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдкреГрд╖реНрдареЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд┐рдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП pageview рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЗрд╡рд▓ рддрдм рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ => рдореЗрд░реЗ рдкрд╛рд╕ рдореЗрд░реА рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ video рдкрдЧреЗрдЯрд╛рдЗрдк рд╣реИ рдФрд░ рдореИрдВрдиреЗ рдЗрд╕рдореЗрдВ рджреЗрдЦрд╛ рдЬреАрдП рд▓рд╛рдЗрд╡ рджреЗрдЦреЗрдВ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рд╡реАрдбрд┐рдпреЛ рдкреЗрдЬреЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░рддреЗ рд╕рдордп рдХреЗрд╡рд▓ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡реАрдбрд┐рдпреЛ рдкреЗрдЬ рдХреЛ рдЯреНрд░реИрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛

рдореИрдВрдиреЗ рдЗрди рджреЛрдиреЛрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдЪреНрдЪ рдХреНрд░рдо рдШрдЯрдХ рдмрдирд╛рдпрд╛ред рдкрд╣рд▓реЗ рдПрдХ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ @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.тАж рдХреА рдХреЙрд▓ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдбреЙрдХреНрдпреВрдореЗрдВрдЯреЗрдб API рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЬрдм рдореИрдВрдиреЗ Router.onRouteChangeComplete рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЬреЛ рдХрд┐ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП , рддреЛ рдореБрдЭреЗ рдПрдХ ReferenceError рдорд┐рд▓рд╛ рдХреНрдпреЛрдВрдХрд┐ onRouteChangeComplete undefined ред рд╢рд╛рдпрдж рдкреНрд░рд▓реЗрдЦрди рдкреБрд░рд╛рдирд╛ рд╣реИ?

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдЕрдЧрд▓реА .js рд╡реЗрдмрд╕рд╛рдЗрдЯ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдФрд░ 'рд╡рд┐рдВрдбреЛ рдиреЙрдЯ рдбрд┐рдлрд╛рдЗрдВрдб' рдПрд░рд░ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдорд┐рд▓рд╛, рдЬрд┐рд╕реЗ рдореИрдВ рд░рд┐рдПрдХреНрд╢рди-рдЧрд╛ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдЪрд▓рд╛ рд░рд╣рд╛ рдерд╛ред

@osartun рд╕рдорд╛рдзрд╛рди рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред рдзрдиреНрдпрд╡рд╛рдж! ЁЯСН

@Osartun рдХреЗ рдХреЛрдб рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВ Google рдХреЗ рдирдП gtag рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ pageview рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ (рдЬреЛ _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 / рдЬреЛ рднреА рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдирд╛рдо рд╣реИ:

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

рдкрд╛рд░реНрдЯреА рдореЗрдВ рджреЗрд░ рд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП, @kylewiedman рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд░рд╛рдЙрдЯрд░ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ 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 рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдПрдХ рд╕рд╛рде рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рдж !!

рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реИ: https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics

рдкрд╛рдпрд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рдо, рдШрдЯрдХ рдореЗрдВ рдореБрдЦреНрдп рд▓реЗрдЖрдЙрдЯ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛рдирд┐рдЧрдо () рдФрд░ рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрддрд╛ рд╣реИред рдпрд╣ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдкреНрд░рд▓реЗрдЦрд┐рдд рд╣реИ, рдХреЛрдИ рд╣рд▓рдЪрд▓ рдирд╣реАрдВ

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

@andylacko рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВрдиреЗ рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдлреЛрд░реНрдХ рдХрд┐рдпрд╛ рдерд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП HTTPS: https://github.com/Vadorequest/react-gtm

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдореЗрд░реЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдпрд╣рд╛рдБ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдпрд╣ рдмрд╛рдж рдореЗрдВ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдореИрдВрдиреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдЙрд╕реА рддрд░реНрдХ рдХреЛ рдЕрдиреНрдп рдЙрдкрдХрд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЬрдм рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕реА рдирдП рдорд╛рд░реНрдЧ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ, рддреЛ _app.js getInitialProps рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рдУрд░ рдЪрд╛рд▓реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред (рдкрд╣рд▓реА рдмрд╛рд░ рдпрд╣ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдЪрд▓реЗрдЧрд╛)ред

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 рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ рдФрд░ рдЧрд╛ рдШрдЯрдирд╛ рдЯреНрд░рд┐рдЧрд░ рд╣реИред

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдореЗрд░реЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдпрд╣рд╛рдБ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдпрд╣ рдмрд╛рдж рдореЗрдВ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдореИрдВрдиреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдЙрд╕реА рддрд░реНрдХ рдХреЛ рдЕрдиреНрдп рдЙрдкрдХрд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЬрдм рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕реА рдирдП рдорд╛рд░реНрдЧ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ, рддреЛ _app.js getInitialProps рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рдУрд░ рдЪрд╛рд▓реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред (рдкрд╣рд▓реА рдмрд╛рд░ рдпрд╣ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдЪрд▓реЗрдЧрд╛)ред

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 рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ рдФрд░ рдЧрд╛ рдШрдЯрдирд╛ рдЯреНрд░рд┐рдЧрд░ рд╣реИред

рд╣реЗ рд╡рд┐рд▓ред рдЖрдкрдХреЗ рд╡реЗрдмрдкреИрдХ рдореЗрдВ ReactGA рд╢рд╛рдорд┐рд▓ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯрд╕рд╛рдЗрдб рдЪрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдЖрдкрдХреЗ рдмрд┐рд▓реНрдб рдЖрдХрд╛рд░ рдкрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреНрд░рднрд╛рд╡ рдбрд╛рд▓рддрд╛ рд╣реИ?

@ChrisEdson https://github.com/react-ga/react-ga рдкреВрд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА 161kb рдХрд╛ рд╣реИ ред

рд╣рдореНрдоред рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реИ!

Thu рдкрд░, 28 рдлрд░рд╡рд░реА, 2019 рдХреЛ 19:01 рдкрд░, рд╡рд┐рд▓рд┐рдпрдо рд▓реА рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @ithub.com рдиреЗ рд▓рд┐рдЦрд╛:

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga рдкреВрд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА 161kb рдХрд╛ рд╣реИред

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рдЙрддреНрддрд░ рд╕реАрдзреЗ рджреЗрдВ, рдЗрд╕реЗ 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 рдкрд░, рдХреНрд░рд┐рд╕ рдПрдбрд╕рди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @ithub.com рдиреЗ рд▓рд┐рдЦрд╛:

рд╣рдореНрдоред рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реИ!

Thu рдкрд░, 28 рдлрд░рд╡рд░реА, 2019 рдХреЛ 19:01 рдкрд░, рд╡рд┐рд▓рд┐рдпрдо рд▓реА рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @ithub.com рдиреЗ рд▓рд┐рдЦрд╛:

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga рдкреВрд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА 161kb рдХрд╛ рд╣реИред

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рдЙрддреНрддрд░ рд╕реАрдзреЗ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/zeit/next.js/issues/160#issuecomment-468395136 , рдпрд╛ рдореНрдпреВрдЯ
рд╕реВрддреНрд░
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa
ред

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдиреЗ рдЯрд┐рдкреНрдкрдгреА рдХреА рд╣реИред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рдЙрддреНрддрд░ рд╕реАрдзреЗ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ, рдпрд╛ рдереНрд░реЗрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВред

рддреЛ рдХреА рдЧрдИ рд╕реНрдХреНрд░рд┐рдкреНрдЯ 15kb рд╣реИред рд╡рд╣ рдХрд╛рдлреА рдЫреЛрдЯрд╛ рд╣реИред

рдореИрдВ рдЕрдкрдиреЗ рд╡реЗрдмрдкреИрдХ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдВрдбрд▓ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдореИрдВ рд╡рд╛рдкрд╕ рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХрд┐рддрдирд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред

~ 500kb рдХреЗ рдХреБрд▓ рдмрдВрдбрд▓ рдЖрдХрд╛рд░ рдХреЗ рднреАрддрд░, рдореЗрд░рд╛ ReactGA рд▓рдЧрднрдЧ 27kb рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЪреАрдЬреЛрдВ рдХреА рднрд╡реНрдп рдпреЛрдЬрдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИред

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдореЗрд░реЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдпрд╣рд╛рдБ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдпрд╣ рдмрд╛рдж рдореЗрдВ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдореИрдВрдиреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдЙрд╕реА рддрд░реНрдХ рдХреЛ рдЕрдиреНрдп рдЙрдкрдХрд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЬрдм рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕реА рдирдП рдорд╛рд░реНрдЧ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ, рддреЛ _app.js getInitialProps рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рдУрд░ рдЪрд╛рд▓реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред (рдкрд╣рд▓реА рдмрд╛рд░ рдпрд╣ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдЪрд▓реЗрдЧрд╛)ред

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 рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ рдФрд░ рдЧрд╛ рдШрдЯрдирд╛ рдЯреНрд░рд┐рдЧрд░ рд╣реИред

рдпрджрд┐ рдЖрдк NextJS 9 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдХреНрд╖рдо рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкреНрд░реАрд░реЗрдиреНрдбрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╣реИред рдЖрд╢реНрдЪрд░реНрдп рд╣реЛрддрд╛ рд╣реИ рдХрд┐ ReactGA.pageview(ctx.asPath); рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмреЗрд╣рддрд░ рдЬрдЧрд╣ рд╣реИ, рдЗрд╕реЗ getInitialProps рд╣рдЯрд╛рдиреЗ рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдо getInitialProps рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕реНрд╡рдд: рдкреВрд░реНрд╡реЗрдХреНрд╖рдг рдХреЛ рдпрд╣рд╛рдБ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдХреЗ рд░реВрдк рдореЗрдВ рдСрдкреНрдЯ-рдЖрдЙрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ: https :

рдЕрдкрдбреЗрдЯ: рдореБрдЭреЗ Google-рдПрдирд╛рд▓рд┐рдЯрд┐рдХреНрд╕ рдЙрджрд╛рд╣рд░рдг (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/use -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 рдХреЗ рд╕реЙрд▓реНрдпреВрд╢рди рдкрд░ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реБрдП, рдпрд╣рд╛рдВ рдПрдХ рд╡рд░реНрдХрд┐рдВрдЧ HOC рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдореИрдВ рдЕрдкрдиреЗ рд▓реЗрдЖрдЙрдЯ рдХрдВрдкреЛрдиреЗрдВрдЯ / рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реВрдВред

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

рдпрд╣ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдЪрд▓ рд░рд╣реЗ рдПрдХ рд░реАрдпрд▓рдЯрд╛рдЗрдо рдЖрдЧрдВрддреБрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЦреБрдж рдХреЛ рдЧреБрдЬрд░рддрд╛ рд╣реИред :)

рдореБрдЭреЗ рдпрд╣ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛ рдорд┐рд▓реА - рдХреНрдпрд╛ рдпрд╣ рдПрдХ рдЕрдиреБрд╢рдВрд╕рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ (рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдЧрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)?

рдореИрдВ рдХрд╣рддрд╛ рд╣реВрдБ рдХрд┐ рдЕрдиреБрд╢рдВрд╕рд┐рдд рддрд░реАрдХрд╛ рдЗрд╕ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ:

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

рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╣рд╛рдВ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХрднреА-рдХрднреА рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЧрд┐рддреБрдм рдХреЗ рдореБрджреНрджреЗ рд╕реНрдЯреИрдХрдУрд╡рд░рдлреНрд▓реЛ рдХреА рддрд░рд╣ рдЕрдзрд┐рдХ рд╣реЛрдВ, рдХреБрдЫ рдЙрддреНрддрд░ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╕рд╡рд╛рд▓ рдХреЗ рдареАрдХ рдмрд╛рдж (рдЬрдм рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрджреЗрд╢ рдФрд░ рдЗрдореЛрдЬреАрдЬрд╝ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИрдВред рдПрдХ рд╡рд┐рдХрд▓реНрдк рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЛ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рддрдХ рд╕реАрдорд┐рдд рдХрд░рдирд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд▓реЛрдЧ рдПрдХ рдирдпрд╛ рдореБрджреНрджрд╛ рдмрдирд╛рдПрдВрдЧреЗред рдЗрд╕рдХреЗ рдмрдЬрд╛рдпред рдФрд░ рдмрдирд╛рддреЗ рд╕рдордп рд╡реЗ рдПрдХ рд╕рдорд╛рди рдореБрджреНрджрд╛ рдкрд╣рд▓реЗ рд╣реА рдмрдирд╛ рд▓реЗрдВрдЧреЗ ("рд╕рдорд╛рди рдореБрджреНрджреЛрдВ" рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж), рдФрд░ рдЗрд╕рдХрд╛ рдЙрддреНрддрд░ рд╣реИ (рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдЗрдореЛрдЬреАрд╕ рд╡рд╛рд▓рд╛ рдЙрддреНрддрд░ рд▓рдВрдмреЗ рдЗрддрд┐рд╣рд╛рд╕ рдХреЗ рдмреАрдЪ рдореЗрдВ рдХрд╣реАрдВ рдЦреЛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╣реИ) рдЬреАрдердм рдкрд░ рдЬрд╡рд╛рдм рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ)ред

рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╣рд╛рдВ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХрднреА-рдХрднреА рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЧрд┐рддреБрдм рдХреЗ рдореБрджреНрджреЗ рд╕реНрдЯреИрдХрдУрд╡рд░рдлреНрд▓реЛ рдХреА рддрд░рд╣ рдЕрдзрд┐рдХ рд╣реЛрдВ, рдХреБрдЫ рдЙрддреНрддрд░ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╕рд╡рд╛рд▓ рдХреЗ рдареАрдХ рдмрд╛рдж (рдЬрдм рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрджреЗрд╢ рдФрд░ рдЗрдореЛрдЬреАрдЬ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИрдВ ...)ред

рдЧрд┐рддреБрдм рдЗрд╕ рд░реЗрдкреЛ рдХреА рдЪрд░реНрдЪрд╛ рдЯреИрдм рдкрд░ рдЗрд╕ рдкрд░ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдмрдирд╛ рд░рд╣рд╛ рд╣реИред

Screenshot 2020-04-08 at 16 59 58

@janbaykara рд╡рд╛рд╣, рд╕рдЪ рдореЗрдВ? рд╣рдо рд╕рднреА рдПрдХ рд╣реА рддрд░рд╣ рд╕реЗ рд╕реЛрдЪрддреЗ рд╣реИрдВ :) рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд╡реЗ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдХрд┐рд╕реА рдореБрджреНрджреЗ рдХреЛ рдПрдХ рдЪрд░реНрдЪрд╛ рдореЗрдВ рддрдмреНрджреАрд▓ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдкрд╛рдПрдВрдЧреЗ, рдпрд╛ рдпрд╣ рдПрдХ рд╣реА рдмрд╛рдд рд╣реЛрдЧреА (рдпрджрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдореБрджреНрджреЛрдВ рдореЗрдВ рдорд┐рд▓рд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рд╕рднреА рдореМрдЬреВрджрд╛ рдЪрд░реНрдЪрд╛рдПрдВ рдореБрджреНрджреЗ рдмрди рдЬрд╛рдПрдВрдЧреА)ред рд▓реЗрдХрд┐рди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

@ 3lonious рдореИрдВрдиреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ Google Analytics рдХреЛ

Next.js рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, https://github.com/UnlyEd/next-right-now/blob/v2-mst-aptd-gcms-lcz-sty/src/compenders/pageLayouts/Head.tsx ( next/Head рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреЗрдЦреЗрдВ ) next/Head ), рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдореИрдВ рдЕрдкрдиреЗ рдРрдкреНрд╕ рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рд╢рд╛рдорд┐рд▓ рдХрд░рддрд╛ рд╣реВрдВред

NRN https://unlyed.github.io/next-right-now рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдореЗрдВ рд╕рдВрдХреЛрдЪ рди

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдпрд╣ рдорд┐рд▓ рдЧрдпрд╛ рд╣реИ, рдореБрдЭреЗ рдЙрд╕ рдлрд╛рдЗрд▓ рдореЗрдВ рдХреЛрдИ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ?

рдпрд╣ рднреА рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЗрд╕реЗ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рдХреГрдкрдпрд╛ рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рдХрд░реЗрдВред

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 рдЦрд╛рддреЗ рдореЗрдВ рдЯреНрд░реИрдлрд╝рд┐рдХ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддрд╛ рд╣реИред

@ 3 рд╡рд┐рд▓рдХреНрд╖рдг рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдФрд░ рд╕реНрдЯрд╛рдЗрд▓ рдЯреИрдЧ рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред
рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╛рдзрд╛рди рднреА, рдЕрдиреБрднрд╡ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред (рдпрд╣ рд╣реИ рдХрд┐ рдореИрдВ рдХреИрд╕реЗ рдЬреАрдП рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛)

рдареАрдХ рд╣реИ рдзрдиреНрдпрд╡рд╛рдж рджреЛрд╕реНрддреЛрдВ im рдХреЛрд╢рд┐рд╢ рдХрд░реЛ рдФрд░ рддреБрдо рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдУ

рдареАрдХ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рд▓рд╛

рдзрдиреНрдпрд╡рд╛рдж рдПрдВрдЯреЛрдиред рдареАрдХ рд╣реИ рдореИрдВ рддреБрдореНрд╣рд╛рд░реЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рд╣реИ haha

рдореЗрд░реЗ рдкрд╛рд╕ рдЧреНрд░рд╛рд╣рдХ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреИрдЯ рдРрдк рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╣ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ dosnt рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ? рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?

рдпрд╣ рдореБрдЭреЗ рд╢рд░реАрд░ рдореЗрдВ рдЗрд╕ рджреВрд╕рд░реЗ рдЯреИрдЧ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд░рд╣рд╛ рд╣реИ? рдЖрдк рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рддреЗ рд╣реИрдВ?
Screen Shot 2020-06-19 at 6 48 22 AM

рдЯреАрдмреАрдЯреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ? рдпрджрд┐ рдЖрдк Google рд╡рд┐рд╢реНрд▓реЗрд╖рд┐рдХреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдЖрдкрдХреЗ рдЧрддрд┐ рд╕реНрдХреЛрд░ рдХреЛ рдзреАрдорд╛ рдХрд░ рджреЗрдЧрд╛

рдЯреАрдмреАрдЯреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ? рдпрджрд┐ рдЖрдк Google рд╡рд┐рд╢реНрд▓реЗрд╖рд┐рдХреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдЖрдкрдХреЗ рдЧрддрд┐ рд╕реНрдХреЛрд░ рдХреЛ рдзреАрдорд╛ рдХрд░ рджреЗрдЧрд╛

рдЗрд╕рдХреА рд╡рдЬрд╣ рд╣реИ рдХрд┐ рд╕рд╛рдордЧреНрд░реА рд╕реЗ рдкрд╣рд▓реЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд░рдЦрдиреЗ рдХреА рдЙрдирдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рд╕рд╛рдордЧреНрд░реА рдХреЗ рддрд╣рдд рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдХреЛрд░ рдиреАрдЪреЗ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛ред

рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдкрд╣рд▓реЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд░рдЦрдиреЗ рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд▓рд╛рдн рдирд╣реАрдВ рджреЗрдЦрддрд╛ред рдпрджрд┐ рдкреГрд╖реНрда рд▓реЛрдб рдХрд┐рд╕реА рддрд░рд╣ рдЯреВрдЯ рдЧрдпрд╛ рдерд╛, рдФрд░ HTML рдХрд┐рд╕реА рддрд░рд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓реЛрдб рдирд╣реАрдВ рд╣реБрдЖ рдерд╛ рдФрд░ рдЗрд╕реЗ рдирд┐рд░рд╕реНрдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдореИрдВ рдЗрд╕реЗ рд╣рд┐рдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдЧрд┐рди рд╕рдХрддрд╛, рдЗрд╕рд▓рд┐рдП рдЬреЛ рднреА рд╣реЛред

рдореИрдВ рдиреЗрдХреНрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореИрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП Google рд╕реНрдерд╛рди рдСрдЯреЛ рдкреВрд░реНрдг API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдФрд░ рдПрдкреАрдЖрдИ рдХреЗ рдЙрди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рдореБрдЭреЗ рдЙрди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдХреЛ рдХрд╣рд╛рдБ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ??

_app.js

`` `Js
"рд░рд┐рдПрдХреНрдЯ-рдЧрд╛" рд╕реЗ рд░рд┐рдПрдХреНрдЯреНрдЯрд╛ рдХреЛ рдЖрдпрд╛рдд рдХрд░реЗрдВ;

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 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

flybayer picture flybayer  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

lixiaoyan picture lixiaoyan  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

swrdfish picture swrdfish  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

renatorib picture renatorib  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ghost picture ghost  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ