Search code examples
reactjsgoogle-analyticscreate-react-appreach-router

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


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?


Solution

  • 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.