如何为React-Router设置Google Analytics?

Joh*_* Fu 63 google-analytics reactjs react-router

我正在尝试在我的反应网站上设置Google Analytics,并且遇到了一些软件包,但是没有一个软件包具有我在示例方面的设置.希望有人可以对此有所了解.

我正在看的包是,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'));
Run Code Online (Sandbox Code Playgroud)

Dav*_*lsh 67

保留对历史对象的引用.即

import { createBrowserHistory } from 'history';

var history = createBrowserHistory();

ReactDOM.render((
    <Router history={history}>
        [...]
Run Code Online (Sandbox Code Playgroud)

然后添加一个监听器来记录每个综合浏览量.(这假设您已经window.ga以通常的方式设置了对象.)

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

  • 这不会考虑发送的事件或其他匹配类型.他们仍然会在页面加载时引用URL.相反,您需要在发送网页浏览之前在跟踪器上设置新值,例如`ga('set','page',location.pathname + location.search); ga('发送','pageview');`. (14认同)
  • 你好,David,你的示例是使用 ga 网站上的常规 ga 代码还是使用 React-ga 包?谢谢。 (2认同)

thi*_*ign 27

由于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;
Run Code Online (Sandbox Code Playgroud)

App.js

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

  return (...);
};
Run Code Online (Sandbox Code Playgroud)

也可以看看:

这是一个更聪明的版本:

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;
Run Code Online (Sandbox Code Playgroud)

  • 我找到的最好、最优雅的解决方案,谢谢。只是考虑一下,要在 App.js 中调用 useLocation,您必须在 index.js 中添加 &lt;Router&gt;,如下所示: &lt;Router&gt;&lt;App /&gt;&lt;/Router&gt; 在顶部导入 Router,并使用 import { BrowserRouter as Router } from '反应路由器 dom'; (4认同)
  • 我不确定最新的“gtag”是否有必要。当我导航时,ga调试器似乎正确记录了推送事件:`处理数据层推送:{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 仪表板中 (2认同)

hey*_*ugo 24

鉴于谷歌分析已加载并初始化跟踪ID.

这是react-router版本4的解决方案,使用该<Route>组件来跟踪页面视图.

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

您只需将此组件呈现在<Router>(但不是a的直接子项<Switch>)内.

会发生的情况是,每当位置道具发生变化时,都会导致重新渲染此组件(实际上不渲染任何内容),从而触发网页浏览.

  • 只要有另一条路线发出您想要的任何东西,@ DanaWoodman。假设路由不在“ Switch”中 (2认同)
  • 这个人值得获得诺贝尔奖,我们已经尝试了各种方法,但这是唯一一个没有缺点的人。谢谢! (2认同)

boz*_*doz 22

我正在使用React Router v4和Google Analytics 全球网站代码,这在撰写本文时似乎是推荐的.

这是我的解决方案:

创建包在一个组件withRouterreact-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);
Run Code Online (Sandbox Code Playgroud)

只需在路由器中添加组件(我认为理想情况是在任何匹配的路由和任何Switch组件之后,因为分析功能不应优先于您的站点渲染):

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>
);
Run Code Online (Sandbox Code Playgroud)

就像声明的那样:

withRouter将在每次路径更改时使用与渲染道具相同的道具重新渲染其组件

因此,当路由发生变化,GoogleAnalytics组件将更新,它将接收新的位置作为道具,并且history.action将或者PUSH一个新的历史项目或POP信号通过历史(我想应该不会触发页面视图倒退,但您可以根据需要调整if语句componentWillUpdate(您甚至可以尝试componentDidUpdate使用this.props,但我不确定哪个更好)).

  • 嘿@JoshuaRobinson,我在底部写道,“......我认为不应该触发页面浏览,但你可以调整......”。这个问题是关于将 Google Analytics 与 React Router 集成,而不是关于您应该记录哪些视图。话虽如此,我可能会调整我的组件,因为 Google 最终会对其进行不同的跟踪。谢谢。 (2认同)

Pet*_*erg 17

请注意,如果您正在使用该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>)
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这需要您安装historypackage(npm install history).这已经是react-router-dom的依赖,所以你不在这里添加任何页面权重.

另请注意:无法使用BrowserRouter组件和仪器以此方式跟踪.这没关系,因为BrowserRouter组件只是Router对象周围非常薄的包装器.我们在这里重现BrowserRouter功能与<Router history={history}>在那里const history = createBrowserHistory();.


Tos*_*she 9

我建议使用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>
Run Code Online (Sandbox Code Playgroud)

  • 如果用户只对跟踪页面浏览量感兴趣,这似乎是一个超级简单的解决方案。很瘦! (3认同)

Par*_*ras 7

始终遵循图书馆推荐的方式

在React-GA文档中,他们添加了建议与React Router一起使用的社区组件: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'),
);
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)


Jöc*_*ker 6

我喜欢Mark ThomasMüller 在这里提出的建议:

在你的index.js中

import ReactGA from 'react-ga'

ReactGA.initialize('YourAnalyticsID')

ReactDOM.render(<App />, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)

您的路线在哪里:

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>
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

简短,可扩展且简单:)