Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Plausible Analytics

A Discourse theme component that sends pageviews and rich custom events to Plausible Analytics — Cloud or self-hosted. Beyond basic page views it tracks topic creation, replies, likes, bookmarks, searches, outbound link clicks, and (optionally) any Discourse appEvent you name.

It exists because just pasting Plausible's snippet into a theme's </head> can't do any of the Discourse-specific work: hooking forum activity as custom events, keeping private messages out of your analytics, and redacting one-time-token URLs before they leave the browser.

Compatibility

Requires Discourse 3.3 or later: the component injects the Plausible script from theme JavaScript, which Discourse's strict-dynamic CSP trusts automatically — no CSP settings to change. (On older Discourse versions you'd have to add your Plausible host to the content_security_policy_script_src site setting.)

Event hooks (topic:created, post:created, page:like-toggled, bookmarks:changed) verified against Discourse core main as of July 2026. All handlers are defensively guarded, so a missing or reshaped event degrades to "that event isn't tracked" rather than a broken site.

How it works

  • The official Plausible script, in manual mode. The component loads script.manual.js from your Plausible instance, so everything the official script does — visit attribution, referrers, engagement time and scroll depth, the plausible_ignore opt-out — works exactly as on any other Plausible site. "Manual" means the script sends nothing on its own: every event is triggered by the component, which applies the privacy rules below first.
  • Pageviews are sent on page:changed, which fires on the initial load and on every in-app route transition (deduplicated by URL).
  • Custom events are subscribed via Discourse appEvents (topic:created, post:created, page:like-toggled, bookmarks:changed), searches are detected from the /search?q=… route, and outbound clicks from a capture-phase click listener (the component's own, not the script's outbound-links extension, so the private-message rule applies to those too).
  • Privacy defaults: no cookies, no user identifiers, private messages and whispers are never tracked, admin pages send nothing by default, search terms are excluded unless you opt in, and the plausible_ignore localStorage flag is honored.

Events sent

Plausible event Fires when Props Toggled by
pageview Initial load and every in-app navigation track_pageviews
Topic Created A user creates a new topic (PMs excluded) category track_topic_created
Post Created A user posts a reply (PMs and whispers excluded) category track_post_created
Post Liked A user likes a post (unliking is not tracked) category track_likes
Post Bookmarked A user bookmarks a post category track_post_bookmarks
Topic Bookmarked A user bookmarks a whole topic category track_topic_bookmarks
Search A full-page search (/search?q=…) is executed term (opt-in) track_search
Outbound Link: Click A visitor clicks a link to another site url track_outbound_links
(your own) Any appEvent listed in forward_app_events forward_app_events

Every event has its own on/off setting in the component's admin UI. On top of these, the official script sends its own engagement events automatically, powering the time-on-page and scroll-depth metrics in the dashboard.

Setup in Plausible

  1. Add your forum as a site in Plausible and note the domain you used.
  2. Custom events only show up once you add them as goals: Site settings → Goals → Add goal → Custom event, using the exact names from the table above.
  3. To break goals down by category, term, or url, enable those keys under Site settings → Custom properties.

Login and sign-up funnels need no custom events — modern Discourse serves them as full pages, so /login and /signup can be tracked as pageview goals.

Install

  1. Admin → Customize → Themes → Components → Install → From a git repository and paste this repo's URL (or From your device with a zip).
  2. Add the component to your active theme.
  3. In the component settings, set plausible_domain to the domain configured in Plausible (or leave blank to use the forum's hostname). Self-hosters: point plausible_host at your instance.
  4. Hard-refresh the forum and watch the events arrive in your Plausible dashboard. Enable debug_mode to see every payload in the browser console.

Settings

Setting Default What it does
plausible_host https://plausible.io Your Plausible instance — the script is loaded from (and events sent to) here
plausible_domain (forum hostname) Which Plausible site records the events (data-domain)
track_pageviews on SPA pageviews
track_topic_created on Topic Created events
track_post_created on Post Created events
track_likes on Post Liked events
track_post_bookmarks on Post Bookmarked events
track_topic_bookmarks on Topic Bookmarked events
track_search on Search events
include_search_term off Attach the query as a term prop (may contain PII)
track_outbound_links on Outbound Link: Click events
include_category_prop on Attach the category name to content events
track_logged_in_users on Turn off to track only anonymous visitors
exclude_staff off Never track admins/moderators
exclude_admins off Never track admins (moderators still tracked)
exclude_admin_pages on No events at all on admin pages (/admin…)
exclude_personal_pages off No events at all on /u/… and /my/… pages
forward_app_events (empty) Extra appEvents to forward verbatim
track_localhost off Also send events from localhost
debug_mode off Log every payload to the browser console

Translations

The component description and every setting description shown in the admin UI are localized via locales/*.yml (Discourse reads them from theme_metadata, matching the admin user's locale and falling back to English). English, German, Spanish, French, and Dutch are included. Add a language by dropping a locales/<code>.yml alongside en.yml with the same keys. Note that setting names (e.g. track_pageviews) and the Plausible event names themselves are not translatable — only the descriptions are.

Tracking more events

Two escape hatches, no code changes required for the first:

  • forward_app_events — list any Discourse appEvent names (e.g. composer:opened) and each is forwarded as a Plausible event of the same name. Discover event names by grepping Discourse core for appEvents.trigger.
  • window.plausible("Event Name", { props: { … } }) — the component exposes the same global the official script does, so other theme components and plugins can send their own events through it.

Privacy notes

  • Nothing is stored on the visitor's device; no cookies or fingerprinting.
  • Private messages and whispers are never tracked, regardless of settings. This is enforced centrally: on a private-message page (the PM itself or the messages inbox) no event of any kind is sent — not pageviews, not outbound clicks, not forwarded appEvents, not window.plausible() calls — because a PM's URL contains its title-derived slug. One consequence of the official script measuring engagement against the last sent pageview: time spent on an untracked page (a PM, or an excluded admin/personal page) can be attributed to the previously viewed tracked page. The untracked URL itself is never sent.
  • The same no-events-at-all rule covers admin pages (/admin…) by default (exclude_admin_pages) — their URLs and search filters can reveal internal details — and, opt-in via exclude_personal_pages, the user profile and preferences pages (/u/…, /my/…), whose URLs contain usernames.
  • URLs of one-time-token pages (password reset, email login, account activation, email confirmation, invite redemption, account association) are redacted to …/redacted before sending, so tokens never leave the browser.
  • include_category_prop will include the names of restricted categories when their members trigger events — turn it off if your category names are themselves sensitive.
  • Visitors can opt out by setting localStorage.plausible_ignore = "true", same as with the official script.

Structure

about.json
settings.yml
locales/en.yml
javascripts/discourse/api-initializers/plausible-analytics.js

License

Apache License 2.0

About

Discourse theme component that sends pageviews and custom events to Plausible Analytics — no external script, no cookies, no CSP changes.

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages