How to set up Google Analytics for React-Router?

后端 未结 15 639
名媛妹妹
名媛妹妹 2020-12-12 12:25

I\'m trying set up Google Analytics on my react site, and have come across a few packages, but none of which has the kind of set up that I have in terms of examples. Was ho

相关标签:
15条回答
  • 2020-12-12 13:00

    here is a simplest way to track all paths with some work arounds:

    npm i --save history react-ga

    create a file 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
    

    and then import it to where is set your 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
    

    References:

    Gustavo Gonzalez | medium.com

    History | GitHub

    0 讨论(0)
  • 2020-12-12 13:03

    Given that google analytics is loaded and initialised with a tracking id.

    Here is a solution for react-router version 4 using the <Route> component to track page views.

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

    You simply render this component inside the <Router> (but not as a direct child of a <Switch>).

    What happens is that whenever the location prop changes it causes a re-render of this component (not actually rendering anything) that fire a pageview.

    0 讨论(0)
  • 2020-12-12 13:03

    I'm using React Router v4 and the Google Analytics Global Site Tag, which appears to be recommended at the time of writing this.

    And here's my solution:

    Create a component wrapped in withRouter from 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);
    

    Simply add the component within your router (I believe ideally after any routes that would be matched and any Switch components, because the analytics function should not be priority over your site rendering):

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

    As stated:

    withRouter will re-render its component every time the route changes with the same props as render props

    So when the route changes, the GoogleAnalytics component will update, it will receive the new location as props, and history.action will be either PUSH for a new history item or POP to signal going backwards through the history (which I think shouldn't trigger a page view, but you can adjust the if statements in componentWillUpdate as you see fit (you could even try componentDidUpdate with this.props instead, but I'm unsure which is better)).

    0 讨论(0)
  • 2020-12-12 13:04

    If you use hash or browser history you can do:

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

    where ./tracking.es6

    export default function(location) {
        console.log('New page hit', location.pathname);
        // Do your shizzle here
    }
    
    0 讨论(0)
  • 2020-12-12 13:05

    Note if you're using the react-router-dom package from react-router-4 you can handle this like so:

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

    Note that this requires you to install the history package (npm install history). This is already a dependency of react-router-dom so you're not adding any page weight here.

    Also note: It is not possible to use the BrowserRouter component AND instrument your ga tracking this way. This is okay because the BrowserRouter component is just a really thin wrapper around the Router object. We recreate the BrowserRouter functionality here with <Router history={history}> where const history = createBrowserHistory();.

    0 讨论(0)
  • 2020-12-12 13:08

    Keep a reference to your history object. i.e.

    import { createBrowserHistory } from 'history';
    
    var history = createBrowserHistory();
    
    ReactDOM.render((
        <Router history={history}>
            [...]
    

    Then add a listener to record each pageview. (This assumes you've already set up the window.ga object in the usual manner.)

    history.listen((location) => {
        window.ga('set', 'page', location.pathname + location.search);
        window.ga('send', 'pageview');
    });
    
    0 讨论(0)
提交回复
热议问题