Distinguish production from development

I’d like to include a partial (google analytics) only for production environment and not on the test environment (because it alters completely the statistics). How can I do so?

1 Like

This is how I do it:

Not perfect, as it depends on always running with -D when in dev, but I have a startup script in dev that I always use, so it works for me.

5 Likes

Thanks :slight_smile: it’s a nice way

@fale

If you want to use a purely js-based approach, this is what I’m currently working with:

<!--layouts/partials/google_analytics.html-->
<script>
(function() {
  if (window.location.hostname === "localhost") {
  	console.log("Local dev, so no Google Analytics.");
    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', 'UA-URGAHERE-1', 'auto');
    ga('send', 'pageview');
  }
})();
</script>

Although @bep, I find it interesting that this works because I didn’t need to tweak it in order for the js to run. That is, it’s been a bit since I wrote this and have learned much about Hugo since…and I’m curious as to why everything in the script tag isn’t scrubbed out by Hugo.

4 Likes

Thanks @bep for this workaround. Could Hugo provide a proper way of conditionally switching between dev and production in templates someday?

A dedicated build option would be better than depending on -D, at least.

Maybe, but you can also be inspired by how the Hugo docs site does it. Look in the base template there.

I do it on Netlify by using Environment Variables.

{{ if eq (getenv "HUGO_ENV") "production" }}
  ... code
 {{ end }}
1 Like

Yes, that construction is great. That way you can set

env = "something"

In config.toml and override it in OS env.

Indeed that works perfectly and seems the good way, thanks!

But I can’t manage to set an environment variable in config.yml, didn’t find Configure with Environment Variables useful, can you help on this @bep?
I tried env: something, env: key=value and

env:
 key: value

I was looking for a solution to the same problem and I had an idea that work for me:

{{ $isDevelopment := false }}

{{- if in (string .Site.BaseURL) "localhost" -}}
    {{ $isDevelopment = true }}
{{- end -}}

Note: This solution will not work if you are running the hugo server command with the flag --bind [YOUR_IP_ADDRESS]

1 Like

To piggyback off of @rdwatters solution, this will disable Google Analytics even if hostname is not localhost by looking for the livereload.js script:

<script>
  (function () {
    var scripts = document.getElementsByTagName("script");

    for (i = 0; i < scripts.length; i++) {
      if (scripts[i].outerHTML.includes("livereload.js")) {
        console.log("Development environment detected, Google Analytics disabled");
        return;
      }
    }

    (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', 'https://www.google-analytics.com/analytics.js', 'ga');

    ga('create', 'UA-XXXXX-Y', 'auto');
    ga('send', 'pageview');
  })();
</script>

Edit: made syntax more terse

1 Like

I discovered a simpler way, using only the variable .Site.IsServer

{{ if .Site.IsServer }}
  do something
{{ end }}
11 Likes

Thanks for the tip @leandro, now I’ve updated my google analytics partial to be

{{ if not .Site.IsServer }}
  {{ with .Site.Params.googleanalytics }}
  <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','https://www.google-analytics.com/analytics.js','ga');
  
  ga('create', '{{ . }}', 'auto');
  ga('send', 'pageview');
  </script>
  {{ end }}
{{ end }}
1 Like

This is a better solution than what I proposed above, @zwbetz, since it was well before the .IsServer method was part of Hugo :slight_smile:

Since version 0.53 the following code works perfectly:

{{ if eq hugo.Environment "production" }}
<yourhtml />
{{ end }}
4 Likes

Now you can even do:

{{ if hugo.IsProduction }}
<yourhtml />
{{ end }}
5 Likes