Patrick Desjardins Blog
Patrick Desjardins picture from a conference

Google Analytic with React and Redux

Posted on: 2018-08-28

I had to integrate Google Analytic in one of our website at Netflix. It's been a while I had to use Google Analytic and the last time was simply copy-pasting the code snippet provided by Google when creating the Analytic "provider" account. The last time was a few years ago and the website was not a single-page application (spa). Furthermore, I the application is using Create-React App (TypeScript version) with Redux. I took a quick look and found few examples on the web but I wasn't satisfied. The reason is that all examples I found were hooking Google Analytic at the component level. I despise having anything in the user interface (UI), React that is not related to the UI.

The first step is to use a library instead of dropping the JavaScript directly into the code.

 npm install --save react-ga 

Next step is to configure the library to set the unique identifier provided by Google. I am using the create-react-app scaffolding and I found the best place to initialize Google Analytic to be in the constructor of the App.ts file. It is a single call that needs to be executed once for the life of the spa.

class App extends React.Component {
  public constructor(props: {}) { 
    super(props); 
    ReactGA.initialize(process.env.NODE_ENV === Environment.Production ? "UA-1111111-3" : "UA-1111111-4"); 
  } 

  public render(): JSX.Element { 
    return <Provider store={store}> <ConnectedRouter history={history}> <AppRouted /> </ConnectedRouter> </Provider>; 
  } 
}

export default App; 

The last step is to have react-router to call the page change when the routing change. React-router is mainly configured in React, but I didn't want to have any more ReactGA code in React. The application I am working uses Redux and I have a middleware that handles route. At the moment, it checks if the route change and analyzes the URL to start fetching data on the backend.

return (api: MiddlewareAPI<AppReduxState>) => (next: Dispatch<AppReduxState>) => 
  <A extends Action>(action: A): A => { 
  // Logic here that check for action.type === LOCATION_CHANGE to fetch the proper data 
  // ... 
  // If action.type === LOCATION_CHANGE we also call the following line: ReactGA.pageview(actionTyped.payload.pathname); 
}; 

The previous code is clean. Indeed, I would rather not have anything inside React, but App.tsx is the entry point and the initialize function injects into the DOM Google's code. The Redux solution works well because the react-router-redux used gives the pathname which is the URL. By using the function "pageview" we are manually sending to Google Analytic a page change.