How to Exclude Google Analytics When Running Under Hugo Local Server

I use this {{ if not .Site.BuildDrafts }}, but I have not tested it in the latest releases.

<!-- GOOGLE ANALYTICS -->
{{ if not .Site.BuildDrafts }}
{{ if .Site.Params.googleAnalytics }}
<script>
  (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
    function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
    e=o.createElement(i);r=o.getElementsByTagName(i)[0];
    e.src='https://www.google-analytics.com/analytics.js';
    r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
    ga('create','{{ .Site.Params.googleAnalytics }}','auto');ga('send','pageview');
</script>
{{ end }}
{{ end }}

@DarwinJS In case you don’t run build drafts locally, I like to just set it in the JavaScript. On phone, but this is what I’m using for the docs concept site:

<!-- Google Analytics -->
{{$gaid := .Site.GoogleAnalytics }}
<script>
(function() {
  if (window.location.hostname === "localhost") {
    console.log("Analytics not running on local dev.");
    return;
  } else {
    (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', '{{$gaid}}', 'auto');
    ga('send', 'pageview');
    ga('create', '{{$gaid | safeJS}}', {
      'siteSpeedSampleRate': 100
    });
  }
})();
</script>
3 Likes

Yup. Same technique as described in the Disquss internal template from rendering on localhost.

https://gohugo.io/extras/comments/ (the Javascript check for “localhost” in current window location is the way.

Here’s a link to the older documentation site (I’m in a hurry)

1 Like

Some great ideas!

A couple follow ups:

  • I must be relying on an internal template because I can’t find where the code is to add the functionality - what template should I create an external version of? Is there a how to?
  • I like @RickCogley’s approach because it seems I only incur the code processing hit during site generation - is there scenarios it does not cover that the java script solution does not?
  • Why isn’t this just the default?
{{ with .Site.GoogleAnalytics }}
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', '{{ . }}', 'auto');
ga('send', 'pageview');
</script>
<script async src='//www.google-analytics.com/analytics.js'></script>
{{ end }}

In your theme template’s head section, don’t call the internal template. If you’re using a ready-made theme, find the relevant bit and comment it out. Then add a link to your copy of this code (you can put it in /layouts/partials/ga.html and call it like {{ partial “ga.html” .}}.

OK, I was able to find it. Was searching for googleanalytics rather than google_analytics.

I changed this reference

{{ template "_internal/google_analytics.html" . }}

to this:

{{ if not .Site.BuildDrafts }}
  {{ template "_internal/google_analytics.html" . }}
{{ end }}

Given that I have no need to customize the actual google analytics code call itself - does this seem like an effective way to prevent google anayltics from being triggered during site previews with hugo internal webserver on my local machine?

1 Like

This is what I do:

{{ if eq (getenv "HUGO_ENV") "production" }}
        {{ template "_internal/google_analytics_async.html" . }}
{{ end }}

which of course, means in production, you set your environment to production. On the command line it looks like this: HUGO_ENV="production"

Thanks @budparr - so that would be on the commandline for hugo to generate the site? If so, I would prefer a solution that automatically knows the difference and acts accordingly.

If you do nothing, (e.g. hugo server) the google analytics template won’t be run.

I’d assume that in production the command would just be part of a build process, so not really anything for you to do there either, other than set it up build environment variables one time.

I guess it could be, but I always felt the onus of the JS-related tidbits were on the user, but per @Hash_Borgir 's comment, we are already including something very similar with the Disquss internal template.

@budparr 's solution is really pretty elegant (and less hackish than my own) if you are in a position where you can just set it and forget it w/r/t the env var.

@budparr - do the preview and build process on the same local machine. Gitlab-ci just copies the site to S3 and does a CloudFront invalidation - it does not generate the site.

@RichCogley - is .Site.BuildDrafts only true when I run “hugo server” then?

This would fail on one server hosting both the main domain and the test domain.

For example, my server hosts https://psychedelicsdaily.com and https://dev.psychedelicsdaily.com where former one is my master branch, the other my testing branch.

A lot of people can’t afford to have multiple VPS simply for a testing branch.

While the solution is how it should be, by using env. variables, I ran into this problem in my baseURL thread, it doesn’t work on a single server hosting mulitple domains/branches (essentially environments).

The better solution for most (who don’t have enough resources to purchase multiple server instances) would be to use a js check as in the internal disqus template trickery mentioned in the docs.

I could possibly use this now, since i’ve moved my testing branch to netlify.

dev.psychedelicsdaily.com is psychedelicsdaily-dev.netlify.com.

But yeah… there it is fellow hugo nerds.

I could certainly be mistaken, but I think that scenario is precisely what environment variables are for.

2 Likes

Perhaps I have totally misunderstood!

Say we have 1 VPS, 2 domains (site.com, dev.site.com).

site.com pulls from master.
dev.site.com pulls from testing.

If we do export HUGO_ENV=production it will then conflict with the dev.site.com testing branch, which expects the HUGO_ENV= testing.

Since there can be only one HUGO_ENV (per user on the server), either you’d have to create more users, or you’d have to buy another server.

Unless I have totally misunderstood something. I might have.

the environment variable is specific to the instance of Hugo you are running, not a user.

Just to be clear @Hash_Borgir when you run Hugo, you run the environment variable before the Hugo command, so this…

in full is,
HUGO_ENV="production" hugo

And HUGO_ENV can be anything, for example: `HUGO_ENV=“testing”

If you run nothing, then the test for the environment variable being “production” is false.

I sometimes put this in my body tag to I make sure I know which environment I have set: {{ with getenv "HUGO_ENV" }} {{ . }}{{ end }}

Hope that’s helpful!

I have no idea how else to say it. It seems that you don’t yet understand the problem. Pondering it over further.

Can HUGO_ENV be both “testing” and “production” at the same time? On the same server, under the same user? …

I’ll repeat again, should it help.

There is 1 server. It hosts 2 domains.

The server is my “production server”, so I would naturally login, and do export HUGO_ENV=“production”.

{{ if eq (getenv “HUGO_ENV”) “production” }} do stuff {{end }}

Then I build my site with this code. Since the ENV VAR has been set to production, it will build with analytics. site.com

Now, this server also houses test.site.com (testing branch).

So, when you biuld the dev.site.com from a testing branch in a diff doc_root, since ENV VAR is “production” it will still build with Analytics.

So, if you set export HUGO_ENV=“testing”, it will build without analytics for dev.site.com.

If you now try to build your site.com it expects “production”, it finds “testing” and builds without analytics.

I hope that helps to understand further the problem w/ this approach on a single server.

One could have two users on the machine.

hugoprod, and hugotest.

login as hugoprod and export HUGO_ENV="produciton"
login as hugotest and export HUGO_ENV=“testing”

hugoprod pulls from master
hugotest pulls from testing

Each user now has their correct env variable set.

What you suggest ONLY works for a single user on a single server.

It’s a method different than using a JS check, but it fails on multienv. systems.

Env. is one. You can’t have multiple values for the same ENV VAR under the same user. One env. One value. That’s how it works.

I think you’re thinking of server environments. I’m speaking specifically of a command you can run with your Hugo build. It has nothing to do with servers or users.

I edited my post. Please refer again. Also, hugo runs in an env. in a server, under a user. That’s how posix systems fucntion for the most part.

Thanks, I hope your posts help someone who has that scenario to deal with.

1 Like