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.html for interactive event tracking, or use plausible_custom_goal front-matter for automatic page-load goals.
  • Conditional execution: Both methods only activate when site.Params.plausible.enable is true and the page lacks plausible_do_not_track: true.
  • Dynamic generation: Use Hugo templates inside plausible_js.html to 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 in layouts/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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →