How to Use Front Matter to Control Plausible Tracking in Hugo

Set the plausible_custom_goal parameter in your page's front matter to automatically trigger custom Plausible events when visitors load specific pages.

The divinerites/plausible-hugo theme provides a streamlined method for firing custom analytics goals directly from Hugo content files. By leveraging front matter parameters, you can define page-specific tracking events without modifying template files or adding inline JavaScript. This approach keeps your analytics logic centralized in the theme while giving content editors granular control over event tracking.

How Front Matter Tracking Works

The theme processes custom goals through the plausible_head.html partial, which runs during every page render. When Hugo builds your site, this partial checks for the presence of a specific front matter key and injects the corresponding tracking code into the page head.

The execution flow follows four distinct steps:

  1. The partial creates a global window.plausible function that serves as the standard Plausible API stub.
  2. It renders the plausible_js.html helper to handle generic onclick events for outbound links.
  3. Immediately after, it checks for the plausible_custom_goal parameter in the page's front matter.
  4. If found, the partial outputs a JavaScript snippet that calls plausible() with your custom goal name when the page loads.

In layouts/partials/plausible_head.html (lines 86-89), the implementation appears as:

/* if parameter "plausible_custom_goal" is set */
{{- with .Params.plausible_custom_goal }}
    plausible('{{ . | safeJS }}');
{{- end }}

This template logic ensures that only pages explicitly defining the parameter receive the extra tracking script, keeping your HTML lean on pages that don't require custom events.

Configuring Custom Goals in Front Matter

You can define tracking goals using static strings, dynamic Hugo variables, or data-driven values. All configurations use the same plausible_custom_goal key in your page's YAML or TOML front matter.

Static Goal Names

For consistent tracking across specific page types, use a hardcoded goal name:

---
title: "Contact page"
plausible_custom_goal: "ContactPageViewed"
---

When visitors load this page, Plausible records the ContactPageViewed event automatically. This method works best for high-value static pages like contact forms, pricing tables, or download confirmations.

Dynamic Goals with Hugo Variables

You can construct goal names dynamically using Hugo's template functions and page variables. The theme processes these values at build time, substituting the rendered string into the JavaScript output.

---
title: "Phone number – Mobile"
plausible_custom_goal: "PhoneClick-{{ .Title | urlize }}"
---

Hugo evaluates {{ .Title | urlize }} during site generation, producing a goal name like PhoneClick-phone-number-mobile. This technique allows you to maintain consistent naming conventions across multiple pages while keeping front matter DRY.

Goals from Data Files

For sites generating content from data sources, you can inject custom goals into dynamically created pages. This approach works within list templates or partials that iterate over site data.

Given a data file at /data/phones.yml:

phones:
  - type: "Mobile"
    number: "+33 1 23 45 67 89"
  - type: "Office"
    number: "+33 1 98 76 54 32"

Generate tracked links within your template:

{{- range .Site.Data.phones.phones }}
---
plausible_custom_goal: "PhoneClick-{{ .type }}"
---
<a href="tel:{{ .number }}">{{ .number }}</a>
{{- end }}

Each generated page fires a distinct goal—PhoneClick-Mobile and PhoneClick-Office—enabling precise analytics for user interactions with different data entities.

Technical Implementation Details

The tracking mechanism relies on Hugo's safeJS function to sanitize the goal name before injection. This prevents template injection vulnerabilities while allowing valid JavaScript string characters.

The plausible_head.html partial executes in the following sequence:

  • First: It establishes the window.plausible queue to handle events before the main Plausible script loads.
  • Second: It includes plausible_js.html for standard link click tracking.
  • Third: It evaluates .Params.plausible_custom_goal using the with action, which only outputs the script block when the parameter exists.

This architecture separates concerns cleanly: the head partial manages all Plausible-related scripts, while individual content files declare their tracking requirements through metadata. No additional JavaScript appears in your content files, maintaining separation of presentation and behavior.

Summary

  • The plausible_custom_goal front matter parameter triggers automatic Plausible event tracking when a page loads.
  • Goal names support both static strings and dynamic Hugo template syntax processed at build time.
  • The logic resides in layouts/partials/plausible_head.html and requires no modifications to content templates.
  • The safeJS filter ensures secure injection of goal names into the generated JavaScript.
  • This method eliminates the need for inline tracking scripts in Markdown or HTML content files.

Frequently Asked Questions

What front matter parameter triggers custom goals?

The plausible_custom_goal parameter controls tracking behavior. When present in a page's front matter, the plausible_head.html partial automatically injects a script that calls plausible('YOUR_GOAL_NAME') immediately after the page loads.

Can I use Hugo template functions in the goal name?

Yes. The theme processes the plausible_custom_goal value through Hugo's templating engine, allowing you to use functions like urlize, lower, or variables like .Title and .Section. These evaluate during site generation, producing static strings in the final HTML output.

Where is the tracking logic implemented?

The core logic resides in layouts/partials/plausible_head.html at lines 86-89, according to the divinerites/plausible-hugo source code. This partial checks for the front matter parameter and conditionally outputs the tracking script using the with action.

Does this method require additional JavaScript in content files?

No. All JavaScript generation happens within the theme's partial templates. Content editors only need to add the plausible_custom_goal key to front matter; the theme handles the rest during the Hugo build process.

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 →