How to Configure Custom Goals in Plausible-Hugo: A Complete Guide
You can configure custom goals in plausible-hugo by creating a layouts/partials/plausible_js.html file with JavaScript helper functions, or by adding plausible_custom_goal: "GoalName" to your content front-matter for automatic page-load tracking.
The plausible-hugo theme by divinerites provides a lightweight integration for Plausible Analytics in Hugo static sites. Understanding how to configure custom goals allows you to track specific user interactions—such as clicking phone numbers or viewing critical pages—beyond standard page view analytics.
Understanding Custom Goal Mechanisms
The theme implements two complementary approaches for configuring custom goals, both controlled through layouts/partials/plausible_head.html. This core partial assembles the Plausible script tag, creates a lightweight window.plausible wrapper to buffer calls before the external script loads, and conditionally renders your custom goal code at lines 80-89.
JavaScript Helper Functions
Create a site-wide partial at layouts/partials/plausible_js.html containing function definitions that wrap plausible('GoalName') calls. The plausible_head.html partial renders this content inside a <script> block at lines 80-86, injecting it directly after the Plausible initialization code. You then invoke these helpers via onclick attributes or other event handlers in your templates.
Front-Matter Page Goals
Add the plausible_custom_goal key to any content file's front-matter. When plausible_head.html renders the page at lines 86-89, it checks for this key and immediately emits plausible('GoalName') after the helper block, firing the goal automatically when the page loads.
Both mechanisms respect the global site.Params.plausible.enable flag and check for the plausible_do_not_track: true page parameter to conditionally disable tracking, as implemented at lines 49-52.
Configuring JavaScript Helper Functions
To track interactive events like button clicks or phone number taps, implement helper functions in a dedicated partial.
First, create layouts/partials/plausible_js.html:
function ClickOnTelephoneNumber() {
plausible('ClickOnTelephoneNumber');
}
This file is included in plausible_head.html using | safeJS, allowing you to use Hugo templating logic inside your JavaScript functions. The function names can be dynamic, but must match the string passed to plausible().
Next, invoke the helper in your templates using an onclick handler:
<a href="tel:+331234567890" onclick="ClickOnTelephoneNumber()">
+33 1 23 45 67 90
</a>
When Hugo builds your site, the helper function becomes available globally on the page, enabling the tracking call when users interact with the element.
Configuring Automatic Page-Level Goals
For goals that should fire immediately when a visitor loads a specific page—such as viewing a contact confirmation or pricing page—use front-matter configuration.
Add the following to your content file:
---
title: "Contact Page"
plausible_custom_goal: "ContactPageViewed"
---
During the build process, plausible_head.html detects this key and injects the tracking call immediately after the helper functions:
<script>
plausible('ContactPageViewed');
</script>
This approach requires no additional JavaScript in your templates and fires as soon as the Plausible script finishes loading.
Advanced: Dynamic Goals from Data Files
You can generate multiple unique goals programmatically using Hugo data files and templating. This is useful when tracking interactions with dynamic content like multiple phone numbers or product categories.
Create a data file at /data/about.yml:
about:
enable: true
about_item:
- plausible: Mobile
phone: "+33 1 23 45 67 89"
- plausible: Home
phone: "+33 9 87 65 43 21"
Then populate layouts/partials/plausible_js.html with a template that generates functions dynamically:
{{- $data := index .Site.Data .Site.Language.Lang }}
{{- if $data.about.about.enable }}
{{- range $data.about.about.about_item }}
function telephone{{ .plausible | safeJS }}About() {
plausible('telephone{{ .plausible | safeJS }}About');
}
{{- end }}
{{- end }}
In your layout template, reference these generated functions:
{{- $data := index .Site.Data .Site.Language.Lang }}
{{- range $data.about.about.about_item }}
{{ $phone_ok := replaceRE "(\\s)" "" .phone }}
<a href="tel:{{ $phone_ok }}" onclick="telephone{{ .plausible | safeJS }}About()">
{{ .phone }}
</a>
{{- end }}
This configuration creates distinct goals (telephoneMobileAbout, telephoneHomeAbout) for each data entry without manually writing separate JavaScript functions.
Integration with Standard Tracking Features
Custom goals work alongside plausible-hugo's built-in outbound link and file download tracking. Enable these features in your site configuration:
[params.plausible]
enable = true
domain = "example.com"
outbound_link = true
file_downloads = true
The plausible_head.html partial automatically appends .outbound-links and .file-downloads to the script URL when these flags are enabled at lines 22-31, allowing custom goals to coexist with automatic external link tracking.
Summary
- Two configuration methods: Create
layouts/partials/plausible_js.htmlfor interactive event tracking, or useplausible_custom_goalfront-matter for automatic page-load goals. - Conditional execution: Both methods only activate when
site.Params.plausible.enableis true and the page lacksplausible_do_not_track: true. - Dynamic generation: Use Hugo templates inside
plausible_js.htmlto generate hundreds of unique goals from data files while maintaining minimal runtime overhead. - File locations: Core logic resides in
layouts/partials/plausible_head.html(lines 49-52, 80-89), while user-defined helpers belong inlayouts/partials/plausible_js.html.
Frequently Asked Questions
How do I disable custom goals on specific pages?
Add plausible_do_not_track: true to the front-matter of any content file. According to the source code in plausible_head.html (lines 49-52), this parameter prevents the entire Plausible script block from rendering, effectively disabling all tracking including custom goals for that page.
Can I use Hugo variables inside my custom goal functions?
Yes. The plausible_js.html partial is rendered with | safeJS in plausible_head.html, allowing full access to Hugo's templating functions. You can reference .Page.Params, .Site.Data, or other context variables to dynamically construct goal names or logic at build time.
What is the difference between plausible_js.html and plausible_custom_goal?
plausible_js.html defines reusable JavaScript functions that you manually trigger via event handlers like onclick, suitable for interactive elements. plausible_custom_goal is a front-matter key that triggers a goal automatically when the page loads, requiring no additional JavaScript or user interaction.
Do custom goals work with Plausible's outbound link tracking?
Yes. Custom goals function independently of outbound link and file download tracking. When you enable outbound_link or file_downloads in your configuration, plausible_head.html modifies the script URL to include these extensions (lines 22-31), while still executing your custom goal code as configured.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →