如何为React-Router设置Google Analytics(分析)?


82

我正在尝试在我的React网站上设置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'));

4
react-router-4/react-router-dom下面发布一个答案,最重要的答案是早期版本的react-router,不幸的是无法在v4上使用。
彼得·伯格

我在使用React SSR时如何在StaticRouter中添加它?
Subhendu Kundu

Answers:


83

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

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软件包?谢谢。
John Fu

还没有决定如何解决它,但是此信息可能也很有用:stackoverflow.com/questions/30052693/…(它解释了为什么在某些情况下归因可能无法正常工作,并且还引入了较高的跳出率)。
DeTeam '16

您不希望在send命令上使用第三个参数。“从技术上来说,针对综合浏览量的send命令接受一个可选的page字段作为第三个参数,不建议在跟踪单个页面应用程序时以这种方式传递page字段。这是因为在跟踪器上未设置通过send命令传递的字段,如果您的应用程序发送了任何非综合浏览量(例如事件或社交互动),则不更新跟踪器会导致问题,因为这些匹配将与跟踪器创建时具有的页面价值相关联。 ”
约书亚·罗宾逊


29

鉴于Google Analytics(分析)已加载并使用跟踪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>

发生的情况是,只要位置prop发生更改,它都会导致该组件的重新渲染(实际上不渲染任何东西),从而触发一次网页浏览。


1
React-router 4.不能执行任何操作吗?!
安东尼·克雷根

1
在下面发布了另一种react-router-4解决方案,该解决方案不涉及修改单个路由。可悲的是,这绝对是“选择您的毒药”类型的情况。
彼得·伯格

1
这不是意味着转到“ /”将什么都不呈现吗?
Dana Woodman

3
只要有另一条路线发出您想要的任何东西,@ DanaWoodman。假设路线不在Switch
bozdoz

这会在目标网页上跟踪两​​次综合浏览量吗?当Google Analytics(分析)自动跟踪着陆页时,我们会为其触发额外的综合浏览量事件。还是GA过滤掉了?
ArneHugo

27

我正在使用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);

只需在路由器内添加组件(我认为,理想情况下,在所有要匹配的路由和任何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>
);

就像声明的那样:

每当路线更改时,withRouter将使用与渲染道具相同的道具重新渲染其组件

因此,当路线更改时,GoogleAnalytics组件将更新,它将以道具的形式接收新的位置,并且history.actionPUSH用于新的历史记录项目,或者POP用于指示向后浏览历史记录(我认为不应触发页面浏览,但是您可以根据自己的需要调整if语句componentWillUpdate(您甚至可以尝试componentDidUpdate使用它this.props,但是我不确定哪种更好)。


bozdoz如何将全球站点标签添加到页面。您是否只是将<script async src =“ googletagmanager.com/gtag/js?id=GA_TRACKING_ID” > </… >添加到body标签下方的html页面中?
me-me

1
@ me-me是的。但在身体标签内:<body> ... <script ...></script></body>
bozdoz

最新的React和React Router需要一些调整。更改componentWillMountcomponentDidMount。将更page_path改为this.props.location.pathname。将Switch和GoogleAnalytics组件包装到<div>
mjhm,

不知道在哪里看到componentWillMount,也不知道有什么page_path不同,但是我会尝试将Switch和GA组件包装在<React.Fragment>而不是中div。谢谢!
bozdoz

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

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对象的一个​​非常薄的包装器。我们在此处使用<Router history={history}>where来重新创建BrowserRouter功能const history = createBrowserHistory();


你从不叫initGA吗?
穆罕默德·乌默尔

@MuhammadUmer是的,请修复它
Peter Berg

您为什么不只在静态HTML中添加GA?我加你一个 因为我认为听历史对象是正确的方法。
文斯五世

@VinceV。可以想象,您可以history在构建中初始化该对象,然后将历史记录存储在该window对象中,并在您脚本中的脚本标签中对其进行访问,<head>但是我认为这最终会使构建管线更加复杂。_(ツ)_ /¯
彼得伯格

如果您使用的是BrowserRouter组件,请参见下面的答案,它提供了替代解决方案。
Toshe

15

我建议使用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>

如果用户只想跟踪页面浏览量,这似乎是一个超级简单的解决方案。很瘦!
peyo

11

我喜欢Mark ThomasMü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>
        )
    }
}

简短,可扩展且简单:)


为什么要跟踪一个全局,一个本地?
Thellimist

10

既然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调试器似乎正确记录了push事件: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

6

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

在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'),
);

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
您可以使用React
Paras

感谢您的发布!
Sailesh Kotha19年

哪里store来的?
user_78361084

哪里Provider以及ConnectedRouter从何而来?这是一个不完整的答案,应该被
否决

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

这里使用哪个路由器版本?
帕万

这是用于反应路由器dom v2或v3,而不是v4
Hugo Gresse

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调用。下面的示例显示了一种执行此操作的方法:

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

@BigDong我不知道closeHeader是什么。您将不得不问OP这个问题,因为渲染代码是他的。我只是在展示您将如何为他的代码实现react-ga(查找我的//注释)
Isaac Pak

0

基于@ david-l-walsh和@bozdoz建议

我创建了一个执行window.ga('set','page','{currentUrl})window.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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.