Skip to main content
  1. posts/

Adding self-hosted analytics to a Hugo site with Plausible

·5 mins
Plausible is a privacy respecting, lightweight and open-source website analytics that is easy to selfhost and add to any site.

Analytics #

Website analytics track visitors to a website by running some Javascript code to collect browsing data. This data is sent to a server, stored in a database and can later be retrieved for analysis. The type of data collected ranges from page-views, unique visitors and geo-location to detailed maps of interactions with elements on the page.

It can be very useful for site owners to know who (geographically) is visiting their site, which pages are popular and how the users are interacting with it. However, clearly there could be privacy issues related to this information and how it is used.

Google analytics is the most popular analytics option, but Google and privacy issues go hand in hand, so I will be avoiding it. There are many other services, both free and paid, but why use an external service when you could host it yourself?

There are a few self-hosted options (that also offer a paid service):

Plausible #

I went with Plausible as it is super lightweight (1.3 kB script) and displays a simple overview of the stats. My purpose for running analytics is out of interest only, so I do not need detailed information. It also respects privacy by preserving anonymity, not using cookies and is even GDPR compliant.

Example of Plausible Analytics stats. [Source: https://plausible.io]

Installation #

Plausible provide a Docker container and a docker-compose file for quick setup. The installation instructions are easy to follow, and after fixing some issues with Docker and nftables, I had it up and running.

The Plausible server is running on the same VPS as the website and listens on port 8000 by default. Accessing it at http://domwil.co.uk:8000 is ok, but a secure connection on its own domain would be far more desirable. To do this requires a reverse-proxy.

I use Caddy as the webserver, so adding a reverse proxy with HTTPS and automatic certs is as simple as adding this to the Caddyfile:

plausible.domwil.co.uk {
reverse_proxy :8000
}

Plausible is now available on https://plausible.domwil.co.uk (after updating the DNS record for the domain). More details about the Caddy setup in this post.

Adding to the website #

Activating the analytics on a website is achieved by adding a Javascript snippet which loads the analytics script on each page on the site. The snippet can be found on the Plausible web interface after setup, mine looks like this:

<script defer data-domain="domwil.co.uk" 
src="https://plausible.domwil.co.uk/js/script.js">
</script>

The snippet fetches the script from the recently configured Plausible server, with the data-domain parameter set to the domain the site is hosted on.

Hugo #

There are a couple of ways of adding Plausible to a Hugo site. One is to use this module, which adds the snippet automatically and allows for fine tuning the behaviour. I had some issues getting this to work, so I went with adding the snippet to a Hugo partial inside <head> tags.

The method for adding the snippet depends on the theme being used. For all themes it should be possible to copy the html partial containing the <head> tags into the local layouts/partials directory, and modify it by adding the snippet. The file in the project directory overwrites the file in the theme directory.

The Congo theme I use contains an analytics.html partial. The layouts/partials/head.html in the theme’s directory contains the following:

<head>
...
{{/* Analytics */}}
{{ partialCached "analytics.html" .Site }}
...
</head>

This imports the analytics.html partial into the <head> tags. Therefore, adding Plausible to every page on the site is done by creating layouts/partials/analytics.html in the project directory, and adding the snippet. However, since I do not want the analytics to run when I am running the development server, the snippet is wrapped in a check for the hugo environment.

{{ if eq hugo.Environment "production" }}

<script defer data-domain="domwil.co.uk" 
    src="https://plausible.domwil.co.uk/js/script.js"></script>

{{ end }}

If you were to open the browser devtools right now you should be able to see the snippet in the header, as shown below.

Screenshot of html head in Firefox devtools
Inclusion of the Plausible snippet shown in Firefox devtools

Update 01/2023 #

Plausible has been up and running for a few months, and I still think its great. The UI is nice and clean, it has all the data I could ever want for a personal blog and it is great fun to see visitors from all over the world:

Screenshot of the top countries of visitors to the site
Screenshot of the top countries of visitors to the site

Custom events #

Not only is it working flawlessly, I recently discovered that Plausible can do custom events. With some very simple javascript, you can call a function to send data back to the plausible server, and get some more specific information.

For example, I recently made a game, and I added functionality to track the number of games being played. This doesn’t happen with normal page views as the page isn’t always refreshed.

Screenshot of the number of games started and finished
Screenshot of the number of games started and finished

Conclusion #

Success! Plausible is installed and running, page visits are being tracked, pretty charts are being plotted. I may look at embedding the stats page on my site at some point, which is something the hugo module should allow, but for now I can sit back and watch the numbers.