Netlify - Add Google Analytics to Hexo on Production-Deploy but Not on Branch-Deploy

How would you know if your website is seen or used? Google Analytics.

For a while I’ve been using Google Analytics to track my blog.
It’s free and it gives me insight on which blog post others find interesting too.
But…I’ve been doing it wrong.

Tools and Workflow

My blog framework is Hexo and I have Continuous Deployment working with the help of Netlify.
When I commit code to master branch, my blog will automatically deploy for your viewing pleasure.
On feature branches, which represents a new post, I configured Netlify’s Branch-Deploy to make my draft post available via a special URL.
I like the Branch-Deploy feature, as I can quickly share it with a friend to get feedback but more importantly, I can compare how the webpage renders on different devices.

My Netlify Build & Deploy => Continuous Deployment => Deploy context settings:

Deploy all branches pushed to Netlify

Adding Google Analytics (GA) to Hexo

Assuming you have a Universal Analytics tracking ID (UA number), adding GA to Hexo blog is very simple.
(If you don’t have a UA number, see resources below to create one)

Just add your Universal Analytics (UA) number to your theme’s ../themes/[YourThemeName]/_config.yml file,
and also add a new ../themes/[YourThemeName]/layout/_partial/google_analytics.ejs file to Hexo.

Add Google Analytics to Hexo

Here is the content of the google_analytics.ejs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<% if (theme.google_analytics){ %>
<!-- Google Analytics -->
<script type="text/javascript">
(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');

ga('create', '<%= theme.google_analytics %>', 'auto');
ga('send', 'pageview');

</script>
<!-- End Google Analytics -->
<% } %>

This works well and below is a sample of the Google Analytics code Hexo will generate in the head section of each page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<head>
...
...
<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-7445566-1"></script>
<script>
window.dataLayer = window.dataLayer || [];

function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'UA-7445566-1');
</script>
<!-- Google Analytics End-->
</head>

My Mistake

After I’ve added GA to my blog, and I browsed the Branch-deploy URL (the test site), I realised GA recorded it as a real-time-active user.

I don’t want any stats recorded when I’m in Test/Draft, I’m only interested in Production stats…oops :)

My mission

How to get Hexo to generate Google Analytics (GA) on Production deployments only.

A quick hexo generate revealed when I remove UA number from the _config.yml, Hexo will remove all GA code from the pages too.

1
2
# Miscellaneous 
google_analytics:

I figured, if I can use Environment Variables to represent the Google Analytics UA tracking number, I would be able add the UA number to the _config.yml for Production deployments and remove it on Branch deployments.

My Solution

After a few minutes in the Netlify documentation, I discovered the awesome Stream Editor linux command sed.
This command will search and replace file content.

Now I have all the info to solve my issue.

Add GA_UA_PLACEHOLDER place holder text in the _config.yml which will be replaced on deployment.

1
2
# Miscellaneous 
google_analytics: GA_UA_PLACEHOLDER

Then, add the Environment Variables and sed (string replace) steps into the netlify.toml.

1
2
3
4
5
6
7
8
9
10
11
[build]
base = "blog"
publish = "blog/public"

[context.production]
environment = { GA_UA_PLACEHOLDER = "UA-7445566-1" }
command = "printenv && sed -i s/GA_UA_PLACEHOLDER/${GA_UA_PLACEHOLDER}/g ./themes/landscape/_config.yml && hexo generate && cp ../prod_headers.txt public/_headers --verbose"

[context.branch-deploy]
environment = { GA_UA_PLACEHOLDER = "" }
command = "printenv && sed -i s/GA_UA_PLACEHOLDER/${GA_UA_PLACEHOLDER}/g ./themes/landscape/_config.yml && hexo generate && cp ../branch_headers.txt public/_headers --verbose"

[context.production]: All steps under this section will execute when commit was detected on master branch.

environment = { GA_UA_PLACEHOLDER = "UA-7445566-1" }: Will set Environment Variable GA_UA_PLACEHOLDER to UA-7445566-1 when changes detected on master.

[context.branch-deploy]: All steps under this section will execute when commit was detected on any feature branch.

environment = { GA_UA_PLACEHOLDER = "" }: Will set Environment Variable GA_UA_PLACEHOLDER to empty string when changes detected on feature deployment.

printenv: Will list all the Environment Variables, just a debug thing I do :)

sed -i s/GA_UA_PLACEHOLDER/${GA_UA_PLACEHOLDER}/g ./themes/landscape/_config.yml: Will take _config.yml file as input and search for all occurrences of GA_UA_PLACEHOLDER and replace it with Environment Variable ${GA_UA_PLACEHOLDER}.

cp ../_headers.txt public/_headers: Will copy branch specific header file _header.txt to public folder with filename _headers, so that Netlify can apply the headers.

After these changes, the head section on each page for feature branches were GA free.
For master commits, the GA “magically” appeared.
Finally, my stats will reflect reality.

Use it…don’t use it :)

PS: Please feel free to leave a comment on how to improve this approach.

Google Analytics Resources

How to add a new website in Google Analytics
Google - Get started with Analytics