In this post, we will go over how we can add a page view “counter” π to our Hugo blog, so we can see how many views each of our posts have had. We will do this using Goatcounter Analytics.
Here is an example of what it may look like:
Goatcounter Set Up
This post assumes you have already created a Goatcounter account, more information here. And you have added Goatcounter analytics to your blog, see this post for more informationPage Views Partial
First, create a new file in your partial folder, in my case, it will be layouts/partials/page_views.html
<span id="{{ .File.UniqueID }}" title="{{ i18n "article.page_views" }}">
</span>
<script>
var r = new XMLHttpRequest();
r.addEventListener('load', function() {
document.getElementById('{{ .File.UniqueID }}').innerText = JSON.parse(this.responseText).count_unique + ' ' + {{ i18n "article.page_views" }}
})
r.open('GET', "https://{{ .Site.Params.goatcounter }}.goatcounter.com/counter/" + encodeURIComponent({{ .RelPermalink }}.replace(/(\/)?$/, '')) + '.json')
r.send()
</script>
We use {{ .File.UniqueID }}
as the id because we may want to display the page views on a page with other articles.
This here will return an MD5 hash of the page. So this will be unique for each blog post/page on your Hugo blog.
We then send an HTTP request to the Goatcounter site for example https://haseebmajid.goatcounter.com/counter/%2Fposts%2F2022-12-15-how-to-use-dotbot-to-personalise-your-vscode-devcontainers.json
.
This will return all the page views for the specific page at /posts/2022-12-15-how-to-use-dotbot-to-personalise-your-vscode-devcontainers/
.
Because I am using the PaperMod theme I adjusted the above HTML slightly. Which adds an emoji and a space between page views and the emoji.
<span class="meta-item">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-activity"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
<span id="{{ .File.UniqueID }}" title="{{ i18n "article.page_views" }}">
</span>
</span>
i18n
Let’s go to our i18n
files and add the following say to i18n/en.yaml
:
- article:
page_views: "Views"
Layouts
Finally find where you actually want to show the page views, in my case I just want to show them in the post themselves and no where else.
So I will go to layouts/_default/single.html
and add the following.
<header class="post-header">
{{ partial "breadcrumbs.html" . }}
<h1 class="post-title">
{{- .Title -}}
{{- if .Draft -}}<sup><span class="entry-isdraft"> [draft]</span></sup>{{- end -}}
</h1>
{{- if .Description }}
<div class="post-description">
{{- .Description -}}
</div>
{{- end }}
{{- if not (.Param "hideMeta") }}
<div class="post-meta">
{{- partial "post_meta.html" . -}}
{{/* TODO move to footer */}}
{{- if .Params.ShowLikes | default site.Params.ShowLikes | default false}}
{{- partial "likes.html" . }}
{{- end }}
{{ if and (.Params.ShowPageViews | default (.Site.Params.ShowPageViews | default true)) }}
{{- partial "page_views.html" . -}}
{{ end }}
{{ partial "edit_post.html" . }}
{{ partial "post_canonical.html" . }}
</div>
{{- end }}
</header>
Site vs Post Params
Note we check for both site params to see if we should show page views.Site.Params.ShowPageViews
.
Or we check if we have turned it off for a specific post .Params.ShowPageViews
(in the frontmatter).That’s it you should be able to have page views on your blog now π!