React-Router用にGoogleAnalyticsを設定するにはどうすればよいですか?


86

私は自分のreactサイトでGoogleAnalyticsをセットアップしようとしていますが、いくつかのパッケージに出くわしましたが、例として私が持っているようなセットアップはありません。誰かがこれに光を当てることができることを望んでいました。

私が見ているパッケージは、react-gaです。

私のレンダリングメソッドはindex.js次のようになります。

React.render((
<Router history={createBrowserHistory()}>
    <Route path="/" component={App}>
        <IndexRoute component={Home} onLeave={closeHeader}/>
        <Route path="/about" component={About} onLeave={closeHeader}/>
        <Route path="/gallery" component={Gallery} onLeave={closeHeader}/>
        <Route path="/contact-us" component={Contact} onLeave={closeHeader}>
            <Route path="/contact-us/:service" component={Contact} onLeave={closeHeader}/>
        </Route>
        <Route path="/privacy-policy" component={PrivacyPolicy} onLeave={closeHeader} />
        <Route path="/feedback" component={Feedback} onLeave={closeHeader} />
    </Route>
    <Route path="*" component={NoMatch} onLeave={closeHeader}/>
</Router>), document.getElementById('root'));

4
以下のための答え投稿react-router-4/react-router-dom以下に、ここでトップの答えは反応し、ルータの以前のバージョンのためのものであり、残念ながらV4としません仕事。
ピーターバーグ

react SSRを使用しているので、StaticRouterでこれを追加するにはどうすればよいですか?
SubhenduKundu19年

回答:


85

履歴オブジェクトへの参照を保持します。すなわち

import { createBrowserHistory } from 'history';

var history = createBrowserHistory();

ReactDOM.render((
    <Router history={history}>
        [...]

次に、リスナーを追加して各ページビューを記録します。(これはwindow.ga、通常の方法でオブジェクトを既に設定していることを前提としています。)

history.listen((location) => {
    window.ga('set', 'page', location.pathname + location.search);
    window.ga('send', 'pageview');
});

16
これは、送信されるイベントまたはその他のヒットタイプを考慮しません。ページの読み込み時に引き続きURLを参照します。代わりに、ページビューを送信する前に、トラッカーに新しい値を設定する必要がありますga('set', 'page', location.pathname + location.search); ga('send', 'pageview');
フィリップウォルトン

1
こんにちはデビッド、あなたの例はgaサイトからの通常のgaコードを使用していますか、それともreact-gaパッケージを使用していますか?ありがとう。
ジョン・フー

修正方法はまだ決まっていませんが、次の情報も役立つ可能性があります:stackoverflow.com/questions/30052693/…(属性が正しく機能しない場合がある理由を説明し、直帰率も高くなります)。
deTeam 2016年

sendコマンドに3番目のパラメーターは必要ありません。「技術的には、ページビューヒットのsendコマンドは3番目のパラメータとしてオプションのページフィールドを受け入れますが、単一ページアプリケーションを追跡する場合、その方法でページフィールドを渡すことはお勧めしません。これは、sendコマンドを介して渡されたフィールドがトラッカーに設定されていないためです。これらは現在のヒットにのみ適用されます。トラッカーを更新しないと、アプリケーションがページビュー以外のヒット(イベントやソーシャルインタラクションなど)を送信した場合に問題が発生します。これらのヒットは、トラッカーが作成されたときに持っていたページ値に関連付けられるためです。 「」
Joshua Robinson


30

グーグルアナリティクスがロードされ、トラッキングIDで初期化されていると仮定します。

これは、<Route>コンポーネントを使用してページビューを追跡するreact-routerバージョン4のソリューションです。

<Route path="/" render={({location}) => {
  if (typeof window.ga === 'function') {
    window.ga('set', 'page', location.pathname + location.search);
    window.ga('send', 'pageview');
  }
  return null;
}} />

このコンポーネントを<Router>(の直接の子としてではなく)内にレンダリングするだけ<Switch>です。

何が起こるかというと、ロケーションプロップが変更されるたびに、このコンポーネントが再レンダリングされ(実際には何もレンダリングされない)、ページビューが発生します。


1
React-router 4.それができないことはありますか?!
Anthony Cregan 2017年

1
個々のルートの変更を伴わない別のreact-router-4ソリューションを以下に投稿しました。悲しいことに、これは間違いなく「あなたの毒を選ぶ」タイプの状況です。
ピーターバーグ

1
これは、「/」に移動しても何もレンダリングされないという意味ではありませんか?
Dana Woodman 2017年

3
@DanaWoodmanが欲しいものを何でも放出する別のルートがあります。これは、ルートがSwitch
bozdoz 2017年

これはランディングページの2つのページビューを追跡しますか?GAがランディングページを自動的に追跡していることを確認すると、追加のページビューイベントがトリガーされます。それともGAはそれを除外しますか?
ArneHugo

27

React Routerv4とGoogleAnalyticsグローバルサイトタグを使用しています。これは、これを書いている時点で推奨されているようです。

そして、これが私の解決策です:

withRouterでラップされたコンポーネントを次の場所から作成しますreact-router-dom

import React from 'react';
import { withRouter } from 'react-router-dom';
import { GA_TRACKING_ID } from '../config';

class GoogleAnalytics extends React.Component {
    componentWillUpdate ({ location, history }) {
        const gtag = window.gtag;

        if (location.pathname === this.props.location.pathname) {
            // don't log identical link clicks (nav links likely)
            return;
        }

        if (history.action === 'PUSH' &&
            typeof(gtag) === 'function') {
            gtag('config', GA_TRACKING_ID, {
                'page_title': document.title,
                'page_location': window.location.href,
                'page_path': location.pathname
            });
        }
    }

    render () {
        return null;
    }
}

export default withRouter(GoogleAnalytics);

ルーター内にコンポーネントを追加するだけです(分析機能はサイトのレンダリングよりも優先されるべきではないため、一致するルートとスイッチコンポーネントの後に理想的に信じています)。

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import IndexPage from './IndexPage';
import NotFoundPage from './NotFoundPage';
import GoogleAnalytics from './GoogleAnalytics';

const App = () => (
    <Router>
        <Switch>
            <Route exact path="/" component={IndexPage} />
            <Route component={NotFoundPage} />
        </Switch>
        <GoogleAnalytics />
    </Router>
);

述べたように:

withRouterは、レンダリング小道具と同じ小道具でルートが変更されるたびに、そのコンポーネントを再レンダリングします

したがって、ルートが変更されると、GoogleAnalyticsコンポーネントが更新され、新しい場所が小道具として受信され、新しい履歴アイテム用にhistory.actionなるか、履歴を逆方向に進むように通知されます(これはページビューをトリガーするべきではないと思いますが、あなたは場合を調整することができます内の文あなたがフィット感を見るように(あなたも試みることができるとの代わりに、私は優れているか不明です))。PUSHPOPcomponentWillUpdatecomponentDidUpdatethis.props


bozdozどのようにしてグローバルサイトタグをページに追加しましたか。HTMLページのbodyタグの下に< scriptasync src = " googletagmanager.com/gtag/js?id=GA_TRACKING_ID "> < / >を追加しましたか?
me-me

1
@ me-meはい。ただし、bodyタグ内:<body> ... <script ...></script></body>
bozdoz 2017

最新のReactおよびReactルーターにはいくつかの調整が必要でした。に変更componentWillMountcomponentDidMountます。をに変更page_paththis.props.location.pathnameます。SwitchコンポーネントとGoogleAnalyticsコンポーネントを<div>でラップします
mjhm 2018年

どこに表示されているのcomponentWillMountか、またどのようにpage_path異なるのかはわかりませんが、の<React.Fragment>代わりにSwitchとGAコンポーネントをラップしてみますdiv。ありがとう!
bozdoz 2018年

2
ねえ@JoshuaRobinson、私は一番下に書いた、「...私はページビューをトリガーするべきではないと思うが、あなたは調整することができる...」。この質問は、ログに記録する必要のあるビューではなく、GoogleAnalyticsをReactRouterと統合することに関するものでした。そうは言っても、Googleがコンポーネントを別の方法で追跡するので、コンポーネントを調整する可能性があります。ありがとう。
bozdoz 2018

19

react-router-domからのパッケージを使用している場合は、react-router-4次のように処理できることに注意してください。

import { Router, Route } from 'react-router-dom';
import { createBrowserHistory } from 'history';

const history = createBrowserHistory();
const initGA = (history) => {
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'YOUR_IDENTIFIER_HERE', 'auto');
  ga('send', 'pageview');

  history.listen((location) => {
    console.log("tracking page view: " + location.pathname);
    ga('send', 'pageview', location.pathname);
  });
};

initGA(history);

class App extends Component { //eslint-disable-line
  render() {
    return
      (<Router history={history} >
         <Route exact path="/x" component={x} />
         <Route exact path="/y" component={y} />
       </Router>)
  }
}

これには、historyパッケージ(npm install history)をインストールする必要があることに注意してください。これはすでにreact-router-domの依存関係であるため、ここではページの重みを追加しません。

また、注意:BrowserRouterコンポーネントを使用して、この方法でgaトラッキングを計測することはできません。BrowserRouterコンポーネントは、Routerオブジェクトの非常に薄いラッパーであるため、これは問題ありません。私たちは、とここBrowserRouter機能を再作成する<Router history={history}>場所const history = createBrowserHistory();


initGAを呼び出すことはありませんか?
Muhammad Umer 2017

@MuhammadUmer true、修正したばかり
Peter Berg

静的HTMLにGAを追加してみませんか?私はあなたに1を加えます。履歴オブジェクトを聞くことが正しい方法だと思うからです。
Vince V.

@VinceV。historyビルド内でオブジェクトを初期化してから、オブジェクトに履歴を保存windowし、のスクリプトタグでアクセスすることもできます<head>が、最終的にはビルドパイプラインがより複雑になると思います。¯_(ツ)_ / ¯–
ピーターバーグ

BrowserRouterコンポーネントを使用している場合は、代替ソリューションを提供する以下の回答を参照してください。
Toshe 2018

14

react-router-ga特にBrowserRouterラッパーを使用する場合は、非常に軽量で構成が簡単な優れたパッケージを使用することをお勧めします。

コンポーネントをインポートします。

import Analytics from 'react-router-ga';

次に<Analytics>BrowserRouter:内に追加するだけです。

<BrowserRouter>
    <Analytics id="UA-ANALYTICS-1">
        <Switch>
            <Route path="/somewhere" component={SomeComponent}/>
        </Switch>
    </Analytics>
</BrowserRouter>

ユーザーがページビューのみを追跡することに関心がある場合、これは非常に単純な解決策のようです。とても痩せています!
ペヨ

11

MarkThomasMüllerがここで提案する方法が好きです

あなたにはindex.js

import ReactGA from 'react-ga'

ReactGA.initialize('YourAnalyticsID')

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

あなたのルートはどこにありますか:

import React, { Component } from 'react'
import { Router, Route } from 'react-router-dom'
import createHistory from 'history/createBrowserHistory'
import ReactGA from 'react-ga'

const history = createHistory()
history.listen(location => {
    ReactGA.set({ page: location.pathname })
    ReactGA.pageview(location.pathname)
})

export default class AppRoutes extends Component {
    componentDidMount() {
        ReactGA.pageview(window.location.pathname)
    }

    render() {
        return (
            <Router history={history}>
                <div>
                    <Route path="/your" component={Your} />
                    <Route path="/pages" component={Pages} />
                    <Route path="/here" component={Here} />
                </div>
            </Router>
        )
    }
}

短く、スケーラブルでシンプル:)


なぜ1つはグローバル、もう1つはローカルの追跡があるのですか?
テリミスト

11

react-router v5.1.0これはではるかに簡単に解決できるのでuseLocation

usePageTracking.js

import { useEffect} from "react";
import { useLocation } from "react-router-dom";
import ReactGA from "react-ga";

const usePageTracking = () => {
  const location = useLocation();

  useEffect(() => {
    ReactGA.initialize("UA-000000000-0");
    ReactGA.pageview(location.pathname + location.search);
  }, [location]);
};

export default usePageTracking;

App.js

const App = () => {
  usePageTracking();

  return (...);
};

参照:

これが少しスマートなバージョンです:

usePageTracking.js

import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import ReactGA from "react-ga";

const usePageTracking = () => {
  const location = useLocation();
  const [initialized, setInitialized] = useState(false);

  useEffect(() => {
    if (!window.location.href.includes("localhost")) {
      ReactGA.initialize("UA-000000000-0");
    }
    setInitialized(true);
  }, []);

  useEffect(() => {
    if (initialized) {
      ReactGA.pageview(location.pathname + location.search);
    }
  }, [initialized, location]);
};

export default usePageTracking;

最新の「gtag」で必要かどうかはわかりません。ナビゲートすると、gaデバッガーがプッシュイベントを正しく記録しているようです。Processing data layer push: {event: "gtm.historyChange-v2", gtm.historyChangeSource: "pushState", gtm.oldUrlFragment: "", gtm.newUrlFragment: "", gtm.oldHistoryState: null, gtm.newHistoryState: {key: "j5xoc4", state: undefined}, gtm.oldUrl: "https://site/", gtm.newUrl: "https://site/new-url?search-params", gtm.triggers: "1_36"}新しいページビューがgaダッシュボードに表示されます
Dattaya 2010年

6

常に図書館の推奨する方法で行ってください

React-GAのドキュメントでは、Reactルーターでの使用が推奨されるコミュニティコンポーネントが追加されています:https//github.com/react-ga/react-ga/wiki/React-Router-v4-withTracker

実装

import withTracker from './withTracker';

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Route component={withTracker(App, { /* additional attributes */ } )} />
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root'),
);

コード

import React, { Component, } from "react";
import GoogleAnalytics from "react-ga";

GoogleAnalytics.initialize("UA-0000000-0");

const withTracker = (WrappedComponent, options = {}) => {
  const trackPage = page => {
    GoogleAnalytics.set({
      page,
      ...options,
    });
    GoogleAnalytics.pageview(page);
  };

  // eslint-disable-next-line
  const HOC = class extends Component {
    componentDidMount() {
      // eslint-disable-next-line
      const page = this.props.location.pathname + this.props.location.search;
      trackPage(page);
    }

    componentDidUpdate(prevProps) {
      const currentPage =
        prevProps.location.pathname + prevProps.location.search;
      const nextPage =
        this.props.location.pathname + this.props.location.search;

      if (currentPage !== nextPage) {
        trackPage(nextPage);
      }
    }

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

  return HOC;
};

export default withTracker;

1
SSR(サーバーサイドレンダリング)を使用する場合、GAはページを更新しないと実際のページのタイトルを認識しません。
フランシスロドリゲス

1
あなたが反応使用してマウントのタイトル変更することができます
パラス

投稿してくれてありがとう!
SaileshKotha19年

どこstoreから来たの?
user_783610 8419

どこんProviderConnectedRouterから来ますか?これは不完全な回答であり、反対票を投じる必要があります
user_783610 8419

2

まず、index.jsでonUpdate関数を設定してgaを呼び出します

import ga from 'ga.js';
onUpdate() {
  console.log('=====GA=====>', location.pathname);
  console.log('=====GA_TRACKING_CODE=====>', GA_TRACKING_CODE);
  ga("send", "pageview", location.pathname);
}

render() {
  return (
    <Router onUpdate={this.onUpdate.bind(this)}>...</Router>
  );
}

そしてga.js:

'use strict';
if(typeof window !== 'undefined' && typeof GA_TRACKING_CODE !== 'undefined') {
  (function(window, document, script, url, r, tag, firstScriptTag) {
    window['GoogleAnalyticsObject']=r;
    window[r] = window[r] || function() {
      (window[r].q = window[r].q || []).push(arguments)
    };
    window[r].l = 1*new Date();
    tag = document.createElement(script),
    firstScriptTag = document.getElementsByTagName(script)[0];
    tag.async = 1;
    tag.src = url;
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  })(
    window,
    document,
    'script',
    '//www.google-analytics.com/analytics.js',
    'ga'
  );

  var ga = window.ga;

  ga('create', GA_TRACKING_CODE, 'auto');

  module.exports = function() {
    return window.ga.apply(window.ga, arguments);
  };
} else {
  module.exports = function() {console.log(arguments)};
}

ここではどのルーターバージョンが使用されていますか?
パバン2017年

これは、v4ではなくreact router dom v2またはv3用です
HugoGresse19年

2

これは、いくつかの回避策を使用してすべてのパスを追跡する最も簡単な方法です。

npm i --save history react-ga

ファイルを作成する history.js

import { createBrowserHistory } from "history"
import ReactGA from "react-ga"

ReactGA.initialize(process.env.REACT_APP_GA)

const history = createBrowserHistory()
history.listen((location) => {
    ReactGA.pageview(location.pathname)
})

// workaround for initial visit
if (window.performance && (performance.navigation.type === performance.navigation.TYPE_NAVIGATE)) {
    ReactGA.pageview("/")
}

export default history

次に、設定されている場所にインポートします Router

import history from "./history"

...

class Route extends Component {
render() {
    return (
        <Router history={history}>
            <Switch>
              <Route path="/" exact component={HomePage} />
              ...
            </Switch>
        </Router>
    )
}

export default Route

参照:

グスタボ・ゴンザレス| medium.com

歴史| GitHub


2

セグメント分析ライブラリを使用し、Reactクイックスタートガイドに従って、react-routerライブラリを使用してページ呼び出しを追跡することをお勧めします<Route />ページがレンダリングされるときにコンポーネントが処理し、componentDidMount呼び出しを呼び出すために使用できるようにすることができpageます。以下の例は、これを行う1つの方法を示しています。

    const App = () => (
      <div>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
        </Switch>
      </div>
    );

    export default App;
    export default class Home extends Component {
      componentDidMount() {
        window.analytics.page('Home');
      }

      render() {
        return (
          <h1>
            Home page.
          </h1>
        );
      }
    }

私はhttps://github.com/segmentio/analytics-reactのメンテナーです。セグメントを使用すると、追加のコードを記述せずに複数の分析ツール(250以上の宛先をサポート)を試すことに興味がある場合は、スイッチを押すだけでさまざまな宛先をオンとオフに切り替えることができます。🙂


1

ハッシュまたはブラウザの履歴を使用する場合は、次のことができます。

import trackingHit from 'tracking';

import { Router, browserHistory } from 'react-router';
browserHistory.listen(trackingHit);
// OR
import { Router, hashHistory } from 'react-router';
hashHistory.listen(trackingHit);

ここで./tracking.es6

export default function(location) {
    console.log('New page hit', location.pathname);
    // Do your shizzle here
}

0

index.jsを使用した基本的なreact-gaの実装

var ReactGA = require('react-ga'); // require the react-ga module
ReactGA.initialize('Your-UA-ID-HERE'); // add your UA code 

function logPageView() { // add this function to your component
  ReactGA.set({ page: window.location.pathname + window.location.search });
  ReactGA.pageview(window.location.pathname + window.location.search);
}

React.render((
<Router history={createBrowserHistory()} onUpdate={logPageView} > // insert onUpdate props here
    <Route path="/" component={App}>
        <IndexRoute component={Home} onLeave={closeHeader}/>
        <Route path="/about" component={About} onLeave={closeHeader}/>
        <Route path="/gallery" component={Gallery} onLeave={closeHeader}/>
        <Route path="/contact-us" component={Contact} onLeave={closeHeader}>
            <Route path="/contact-us/:service" component={Contact} onLeave={closeHeader}/>
        </Route>
        <Route path="/privacy-policy" component={PrivacyPolicy} onLeave={closeHeader} />
        <Route path="/feedback" component={Feedback} onLeave={closeHeader} />
    </Route>
    <Route path="*" component={NoMatch} onLeave={closeHeader} />
</Router>), document.getElementById('root'));

@BigDongcloseHeaderが何であるかわかりません。レンダリングコードは彼のものであるため、OPにその質問をする必要があります。彼のコードにreact-gaを実装する方法を示しています(私の//コメントを探してください)
Isaac Pak

0

@ david-l-walshと@bozdozの提案に基づく

window.ga('set','page','{currentUrl})andwindow.ga('send', 'pageview');関数を実行し、ルーターページで直接簡単に使用できるHOCを作成しました...

これはHOCです:

import React from 'react';
import { history } from '../../store'; // or wherever you createBrowserHistory(); invokation is

function withGAHistoryTrack(WrappedComponent) {
  return class extends React.Component {
    constructor(props) {
      super(props);
    }

    componentDidMount() {
      const { location } = history;
      const page = location.pathname + location.search;

      if (typeof window.ga === 'function') {
        window.ga('set', 'page', page);
        window.ga('send', 'pageview');
      }
    }

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

export default withGAHistoryTrack;

ルーターページでは次のように使用されます。

<Route
 path={'yourPath'}
 component={withGAHistoryTrack(yourComponent)}
 exact
/>

0

一部のイベント(onClickなど)でURLを動的に更新するには、以下を使用できます。

 //Imports
 import ReactGA from "react-ga";
 import { createBrowserHistory } from "history";

 // Add following on some event, like onClick (depends on your requirement)
 const history = createBrowserHistory();
 ReactGA.initialize("<Your-UA-ID-HERE>");
 ReactGA.pageview(history.location.pathname);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.