How to track page views in react using reach router and google analytics?

4k Views Asked by At

I'm porting backbone app to React app. in backbone app I have the following snippet

    <!-- Begin UA code -->
    <script>
    window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
    ga('create', 'UA-xxx', 'auto');

    // Load plugins

    // Rewrite all GA pages with /ra_minisite prefix
    ga('require', 'cleanUrlTracker', {
      stripQuery: true,
      queryDimensionIndex: 1,
      urlFieldsFilter: function(fieldsObj, parseUrl) {
        fieldsObj.page = '/ra_minisite'+parseUrl(fieldsObj.page).pathname
        return fieldsObj;
      },
    });

    ga('require', 'eventTracker');
    ga('require', 'maxScrollTracker');

    // Customize so WS.com not tracked as outbound link
    ga('require', 'outboundLinkTracker');

    ga('require', 'socialWidgetTracker');
    ga('require', 'urlChangeTracker');

    // Commented out so we can call after all API calls are done
    // Called from metaManager
    // ga('send', 'pageview');

    </script>
    <script async src="https://www.google-analytics.com/analytics.js"></script>
    <script async src="/autotrack.js"></script>
    <!-- end UA code -->

And then on each page render after updating meta tags it calls

window.ga('send', 'pageview');

I assume I can just drop init logic into index.html, but what would be a nice, simple way to hook window.ga('send', 'pageview'); into reach router, so that when route changes or updates, pageview would be sent to GA?

3

There are 3 best solutions below

1
On BEST ANSWER

You can listen to the global history object. In your App.js:

import { globalHistory } from '@reach/router';

globalHistory.listen(({ location }) => {
  window.ga('send', 'pageview');
  // or use the new gtag API
  window.gtag('config', 'GA_MEASUREMENT_ID', {'page_path': location.pathname});
});

This is the easiest way, with the least amount of code, and, unlike the LocationProvider method presented in the top answer, it doesn't break the global navigate API.

Unfortunately it appears globalHistory is not documented anywhere, so this was a hard find.

5
On

You can manually create the history object that you can listen to for changes with the createHistory function. You could attach a listener and send a pageview event there.

Example

import { createHistory, LocationProvider } from '@reach/router';

const history = createHistory(window);

history.listen(() => {
  window.ga('send', 'pageview');
});

const App = () => (
  <LocationProvider history={history}>
    <Routes />
  </LocationProvider>
);
0
On

You can use the location provider API from reach router:

import { Router,createHistory,LocationProvider }from "@reach/router";
import ReactGA from "react-ga";
ReactGA.initialize("UA-103xxxxx-xx");
const history= createHistory(window);
history.listen( window => {
  ReactGA.pageview(window.location.pathname+ window.location.search);
  console.log('page=>',window.location.pathname);
});

And then in use it in the route:

<LocationProvider history={history}>
  <Router></Router>
</LocationProvider>

Here is the complete solution.