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
I like how Mark Thomas Müller suggests here:
In your index.js
import ReactGA from 'react-ga'
ReactGA.initialize('YourAnalyticsID')
ReactDOM.render(<App />, document.getElementById('root'))
Where your routes are:
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>
)
}
}
Short, scalable and simple :)
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'));
For dynamically updating url on some event (like onClick etc), following can be used:
//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);
Based on @david-l-walsh and @bozdoz suggestions
I created a HOC that execute the window.ga('set','page','{currentUrl})
and window.ga('send', 'pageview');
function and is easly used directly in the router page...
this is the 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;
and is used this way in the router page:
<Route
path={'yourPath'}
component={withGAHistoryTrack(yourComponent)}
exact
/>
Since react-router v5.1.0 this can be solved a lot easier with 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 (...);
};
See also:
Here's a bit smarter version:
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;
Always go with the library's recommended way
In the React-GA documentation, they have added a community component recommended for using with React Router: https://github.com/react-ga/react-ga/wiki/React-Router-v4-withTracker
Implementation
import withTracker from './withTracker';
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<Route component={withTracker(App, { /* additional attributes */ } )} />
</ConnectedRouter>
</Provider>,
document.getElementById('root'),
);
Code
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;