# How to Use Variable Custom Goals in Plausible-Hugo: Complete Implementation Guide

> Learn how to implement variable custom goals in Plausible Hugo using dynamic event names and Hugo's templating system. Track your website's performance with precise, data-driven insights.

- Repository: [divinerites/plausible-hugo](https://github.com/divinerites/plausible-hugo)
- Tags: how-to-guide
- Published: 2026-02-28

---

**Track custom events in Plausible Analytics using dynamic, data-driven goal names by leveraging Hugo's templating system and the [`plausible_js.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_js.html) partial.**

The `divinerites/plausible-hugo` module provides a lightweight integration for Plausible Analytics in Hugo sites. Beyond basic pageview tracking, it supports **variable custom goals**—dynamic event names generated from data files, page parameters, or site variables—enabling scalable analytics for large sites without hardcoding JavaScript for every individual action.

## Understanding the Architecture

The integration relies on three core components defined in [`layouts/partials/plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/layouts/partials/plausible_head.html):

1.  **[`plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_head.html)** – The engine that constructs the Plausible script URL, initializes the `window.plausible` queue, and conditionally injects custom goal logic.
2.  **[`plausible_js.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_js.html)** – A user-created partial where you define JavaScript helper functions. This is rendered as raw JavaScript (`| safeJS`) inside [`plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_head.html), allowing full use of Hugo templating to generate dynamic function names and calls.
3.  **Front-matter `plausible_custom_goal`** – A declarative key that triggers an automatic goal event when a specific page loads.

Both mechanisms respect the global `site.Params.plausible.enable` setting and respect user privacy via the `plausible_do_not_track` page parameter.

## Method 1: JavaScript Helper Functions

For one-off custom events triggered by user interactions, create reusable JavaScript functions.

### Creating the Helper Partial

Create a file at [`layouts/partials/plausible_js.html`](https://github.com/divinerites/plausible-hugo/blob/main/layouts/partials/plausible_js.html) in your site root:

```javascript
// layouts/partials/plausible_js.html
function ClickOnTelephoneNumber() {
    plausible('ClickOnTelephoneNumber');
}

```

This partial is automatically detected by [`plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_head.html) and injected into the page's `<script>` block, making the `ClickOnTelephoneNumber` function available globally.

### Invoking Goals in Templates

Reference the function in any Hugo template using an `onclick` handler:

```html
<a href="tel:+331234567890"
   onclick="ClickOnTelephoneNumber()">
   +33 1 23 45 67 90
</a>

```

When a visitor clicks the link, the helper function fires the `plausible()` call with the specified goal name.

## Method 2: Automatic Page-Level Goals

To track a goal immediately when a page loads—useful for "thank you" pages or specific landing pages—use front-matter configuration.

Add the `plausible_custom_goal` key to any content file:

```yaml
---
title: "Contact Confirmation"
plausible_custom_goal: "ContactFormSubmitted"
---

```

During the build, [`plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_head.html) checks for this key. If present, it renders:

```html
<script>
    plausible('ContactFormSubmitted');
</script>

```

This executes immediately after the Plausible script initializes, capturing the event without requiring user interaction.

## Method 3: Dynamic Variable Custom Goals from Data

The most powerful feature is generating goal names dynamically from Hugo data files or site parameters. This enables tracking hundreds of unique events—such as clicks on different phone numbers or downloads of specific files—without manually writing JavaScript for each.

### Setting Up the Data Source

Create a data file at [`/data/locations.yml`](https://github.com/divinerites/plausible-hugo/blob/main//data/locations.yml):

```yaml
locations:
  - name: "Paris Office"
    plausible_goal: "ParisPhone"
    phone: "+33 1 23 45 67 89"
  - name: "London Office"
    plausible_goal: "LondonPhone"
    phone: "+44 20 7946 0958"

```

### Generating Functions Dynamically

In [`layouts/partials/plausible_js.html`](https://github.com/divinerites/plausible-hugo/blob/main/layouts/partials/plausible_js.html), loop through the data to create unique functions:

```go
{{- $data := index .Site.Data .Site.Language.Lang }}
{{- if $data.locations }}
  {{- range $data.locations.locations }}
    function {{ .plausible_goal | safeJS }}Click() {
        plausible('{{ .plausible_goal | safeJS }}');
    }
  {{- end }}
{{- end }}

```

This generates JavaScript functions named `ParisPhoneClick()` and `LondonPhoneClick()` at build time.

In your template, invoke these dynamically:

```go
{{- $data := index .Site.Data .Site.Language.Lang }}
{{- if $data.locations }}
  {{- range $data.locations.locations }}
    {{ $phone_clean := replaceRE "(\\s)" "" .phone }}
    <a href="tel:{{ $phone_clean }}"
       onclick="{{ .plausible_goal | safeJS }}Click()">
       {{ .phone }}
    </a>
  {{- end }}
{{- end }}

```

Each phone link now triggers a distinct Plausible goal based on the data file, enabling granular analytics without code duplication.

## Integration with Other Tracking Features

Variable custom goals work alongside Plausible's built-in extensions. Enable additional tracking in your [`config.toml`](https://github.com/divinerites/plausible-hugo/blob/main/config.toml):

```toml
[params.plausible]
enable = true
domain = "example.com"
outbound_link = true
file_downloads = true

```

[`plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_head.html) automatically appends `.outbound-links` and `.file-downloads` to the script URL when these flags are active. Your custom goals will fire alongside these automatic events without conflict.

## Summary

- **JavaScript Helpers**: Create [`layouts/partials/plausible_js.html`](https://github.com/divinerites/plausible-hugo/blob/main/layouts/partials/plausible_js.html) to define reusable `onclick` functions for interactive events.
- **Page-Level Goals**: Use the `plausible_custom_goal` front-matter key to fire goals automatically when a page loads.
- **Variable Goals**: Leverage Hugo's `range` loops and data files in [`plausible_js.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_js.html) to generate dynamic goal names and functions at build time.
- **Conditional Loading**: All goal mechanisms respect the global `enable` flag and the `plausible_do_not_track` page parameter.

## Frequently Asked Questions

### How do I disable tracking on specific pages while keeping custom goals active elsewhere?

Add `plausible_do_not_track: true` to the front-matter of any page. The [`plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_head.html) partial checks for this parameter and skips injecting the Plausible script and any custom goal logic for that specific page.

### Can I use Hugo variables inside the [`plausible_js.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_js.html) partial?

Yes. The partial is rendered with `| safeJS` inside [`plausible_head.html`](https://github.com/divinerites/plausible-hugo/blob/main/plausible_head.html), which means you can use any Hugo templating syntax—such as `{{ .Params.custom_goal }}`, `{{ .Site.Data }}`, or `range` loops—to dynamically generate JavaScript function names and goal identifiers at build time.

### What happens if I define both a front-matter goal and a JavaScript helper on the same page?

Both will execute. The front-matter `plausible_custom_goal` fires immediately when the page loads, while JavaScript helpers fire when the specific event (e.g., `onclick`) occurs. Ensure the goal names are distinct to avoid duplicate events in your Plausible dashboard.

### Is there a limit to how many variable custom goals I can generate from a data file?

There is no hard limit imposed by the `plausible-hugo` module. However, since all goal functions are rendered into the HTML at build time, generating thousands of goals could increase page weight. For high-volume scenarios, consider using a single dynamic goal with custom properties (if supported by your Plausible version) or grouping similar actions under broader goal categories.