How to Integrate Plausible-Hugo with Multilingual Sites: Complete Configuration Guide
Plausible-Hugo integrates seamlessly with multilingual Hugo sites by reading per-language parameters from site.Params.plausible, automatically inheriting global settings when language-specific values are absent.
The divinerites/plausible-hugo module leverages Hugo's native multilingual architecture to deliver analytics across language versions without code duplication. Because the module reads configuration directly from the site's parameter table, it respects language-specific overrides while maintaining global defaults, allowing you to track all languages under one Plausible domain or configure distinct settings per locale.
Architecture of Plausible-Hugo Multilingual Support
The module determines which configuration to apply by evaluating the current language context through Hugo's site.Language object, merging parameters according to Hugo's standard inheritance hierarchy.
Core Components
| Component | Function | Location | Multilingual Behavior |
|---|---|---|---|
plausible_head.html |
Generates the <script> tag, preconnect links, CSP helpers, and custom goal bootstrap |
layouts/partials/plausible_head.html |
Reads site.Params.plausible.* for the active language. Emits script only if enable is true and the page lacks plausible_do_not_track. |
plausible_check.html |
Validates configuration and displays console reminder | layouts/partials/plausible_check.html |
Shows GitHub star hint only for default language (site.Language == site.Sites.Default.Language). |
plausible_js.html |
User-defined custom goals and event functions | layouts/partials/plausible_js.html |
Supports language-specific goal names via .Site.Language.Lang. |
| i18n catalogue | Translation strings for console messages | i18n/en.toml, i18n/fr.toml |
Add <lang>.toml files for additional languages using the plausible_gitstar key. |
Language Parameter Inheritance
Hugo merges language-specific params with global params using a hierarchical lookup. When rendering a French page, Hugo resolves site.Params.plausible.enable in this order:
[languages.fr.params.plausible](language-specific override)[params.plausible](global default)- Module defaults
This inheritance allows you to define common settings once globally while overriding specific values—such as disabling tracking for a particular language—without duplicating the entire configuration block.
Step-by-Step Configuration for Multilingual Sites
1. Define Languages in config.toml
Configure your multilingual structure with language blocks. The defaultContentLanguage establishes which language serves as the default for the console reminder and fallback parameters.
defaultContentLanguage = "en"
[languages]
[languages.en]
languageName = "English"
weight = 1
[languages.fr]
languageName = "Français"
weight = 2
[languages.de]
languageName = "Deutsch"
weight = 3
2. Configure Per-Language Plausible Parameters
Add the params.plausible table under each language block to control tracking per locale. Global settings act as defaults.
[params.plausible]
enable = true
domain = "example.com"
outbound_link = true
[languages]
[languages.en]
languageName = "English"
weight = 1
[languages.en.params.plausible]
enable = true
# Inherits domain from global params
[languages.fr]
languageName = "Français"
weight = 2
[languages.fr.params.plausible]
enable = true
# You can override domain here if using language-specific domains
[languages.de]
languageName = "Deutsch"
weight = 3
[languages.de.params.plausible]
enable = false # Disables tracking for German pages
3. Insert the Partial Template
Include the Plausible head partial in your base layout. The same partial serves all languages automatically by reading the current language's parameters.
<!-- layouts/_default/baseof.html -->
<!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}">
<head>
<meta charset="UTF-8">
<title>{{ .Title }}</title>
{{ partial "plausible_head.html" . }}
</head>
<body>
{{ block "main" . }}{{ end }}
</body>
</html>
The plausible_head.html partial evaluates site.Params.plausible.enable for the current language context, ensuring the analytics script only loads for languages where tracking is enabled.
4. Add Internationalization Strings
Create i18n files for each supported language to translate the console reminder. Copy the existing structure from i18n/en.toml or i18n/fr.toml.
# i18n/en.toml
[plausible_gitstar]
other = "*** Please consider leaving a star on GitHub if you like this Plausible-Hugo module.\n Remove this warning by adding `gitstar = false` in your Plausible configuration."
# i18n/fr.toml
[plausible_gitstar]
other = "*** Merci de laisser une étoile sur GitHub si vous aimez ce module Plausible-Hugo.\n Supprimez cet avertissement en ajoutant `gitstar = false` dans votre configuration Plausible."
The plausible_check.html partial displays this message only when site.Language matches site.Sites.Default.Language, preventing duplicate console messages across language versions.
5. Implement Language-Specific Custom Goals
Create layouts/partials/plausible_js.html to define custom event tracking that varies by language. Access the language code via .Site.Language.Lang.
{{- $lang := .Site.Language.Lang -}}
<script>
// Language-prefixed goal function
function trackDownload{{ $lang | upper }}() {
plausible('Download{{ $lang | upper }}');
}
// Generic goal with language property
function trackContact() {
plausible('Contact', {props: {language: '{{ $lang }}'}});
}
</script>
This approach generates distinct goal names (e.g., DownloadEN, DownloadFR) or passes language as an event property, enabling segmentation by language in your Plausible dashboard.
Key Implementation Details
How the Default Language Check Works
The plausible_check.html partial implements a strict equality check to limit the GitHub star reminder to the default language:
{{ if eq site.Language site.Sites.Default.Language }}
{{ i18n "plausible_gitstar" | safeJS }}
{{ end }}
This comparison evaluates the current rendering context's language object against the default site language. If you require the console reminder for all languages, override this partial in your site's layouts/partials/plausible_check.html and remove the conditional wrapper.
Parameter Merging Behavior
Hugo resolves site.Params.plausible using a cascading lookup mechanism. For a French page (/fr/), the evaluation order is:
site.Params.plausiblefrom[languages.fr.params.plausible]site.Params.plausiblefrom global[params.plausible]- Internal module defaults
This inheritance allows you to set domain globally while toggling enable per language, or override the outbound_link setting for specific locales without repeating the entire configuration block.
Summary
- Plausible-Hugo integrates with multilingual Hugo sites by reading per-language parameters from
site.Params.plausible, automatically inheriting global settings when language-specific values are absent. - Configure each language in
config.tomlwith[languages.xx.params.plausible]blocks to control tracking per locale, including enabling/disabling analytics or using different domains. - Include the single partial
{{ partial "plausible_head.html" . }}in your base template; it automatically respects the current language's configuration. - Provide i18n translations via
i18n/*.tomlfiles for the console reminder, which displays only for the default language unless you overrideplausible_check.html. - Implement language-specific custom goals in
layouts/partials/plausible_js.htmlusing.Site.Language.Langto segment events by language in your Plausible dashboard.
Frequently Asked Questions
Can I use different Plausible domains for different languages?
Yes. While most multilingual sites track all languages under one domain, you can override the domain parameter per language in your config.toml. For example, set [languages.fr.params.plausible] domain = "fr.example.com" while keeping the global domain as example.com. The plausible_head.html partial reads site.Params.plausible.domain for the current language context, so each language version will load the appropriate tracking domain.
Why does the GitHub star reminder only appear for the default language?
The plausible_check.html partial contains a conditional {{ if eq site.Language site.Sites.Default.Language }} that restricts the console message to the default language defined in defaultContentLanguage. This prevents duplicate console messages when users navigate between language versions. If you want the reminder to appear for all languages, copy the partial to your site's layouts/partials/plausible_check.html and remove the conditional wrapper while keeping the i18n lookup.
How do I test Plausible integration on a multilingual site locally?
Add debug = true to the params.plausible block of the specific language you want to test. For example, set [languages.en.params.plausible] debug = true in your config.toml. When running hugo server, the plausible_head.html partial will render the analytics script for that language even in development mode. Remember to remove the debug flag or set it to false before building for production to ensure accurate data collection.
Can I disable Plausible for specific languages only?
Yes. Set enable = false in the params.plausible block for any language you want to exclude. For example, to disable tracking for German while keeping it active for English and French, add [languages.de.params.plausible] enable = false to your configuration. The plausible_head.html partial checks site.Params.plausible.enable for the current language context and will skip rendering the analytics script for that language version, effectively disabling tracking for those pages.
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 →