image by: https://unsplash.com/@davidclode
The Problem :
Google analytics requires a Page URL to track analytics inside of the GA dashboard. Single Page applications only have mock transitions and are not actually changing there URL like classic webpages.
The Solution:
Using React-router , we have access to the powerful History API that uses the browser to manipulate the URL to look and function like an authentic page change.
Sources:
How to make Google Analytics work in a Single Page Application (SPA)
index.html
in the header of the index.html
page, load the script to load google analytics
<script>
(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', '//www.google-analytics.com/analytics.js', 'ga');
</script>
app.js
Inside app.js
on componentDidMount()
create an instance of GA script and attach it to the window so we have access to it at all times.
componentDidMount(){
window.ga('create', 'UA-XXXXXXX-X', 'auto');
}
app.js
create a method that takes in a url
and sets the page view , then sends the view to google analytics:
setPageAndSendToGA = url => {
window.ga('set', 'page', url);
window.ga('send', 'pageview');
};
Next, Create a method that takes in the location provided by this.props.location
.
Build a conditional that fires our setPageAndSendToGA()
whenever a specific URI path is passed in.
...
trackGoogleAnalytics = location => {
if (window.ga) {
if (location.pathname == '/sign-up') {
let url = location.pathname;
this.setPageAndSendToGA(url);
}
if (location.search.length == 10) {
// here we are using search Params, so we concat it to the url string
let url = location.pathname + location.search;
this.setPageAndSendToGA(url);
}
}
};
...
app.js
Then in the render()
we call the function, and it will fire every time the page location
changes
render(){
this.trackGoogleAnalytics(this.props.location);
}
Checkout the article listed above in the sources, for a more detailed explanation, this is just my adapted implementation I used for our app.
TROLL ME:
there is probably a better time to run this function , instead of the render. for our use case, this render is in the top most component in
app.js
there might be a better way to listen for page changes in
browserRouter
object , instead of using theprops.location
please feel free to critique me below in the comments so i can learn to! or make adjustments to the article.
Top comments (2)
How does implementing Google Analytics this way impact your application if Google's script fails to load?
Nice observation !
I actually didn’t even plan for google to fail at anything hahahahaha
But , luckily this method will be unphased by google analytics failing because what it’s doing is checking to see if the ga function is loaded in the first place .
If you look at trackgoogleanalytics() you can see that the first conditional checks if the method is attached to the window object , if not then none of the code runs