# Advanced Google Analytics (v4)

**URL:** https://meta.discourse.org/t/advanced-google-analytics-v4/412327
**Category:** Plugin
**Tags:** analytics
**Created:** [September 14, 2026, 3:14am UTC](https://meta.discourse.org/t/advanced-google-analytics-v4/412327 "2026-09-14T03:14:19Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![AJ\_Quick](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/aj_quick/32/569383_2.png) [@AJ\_Quick](https://meta.discourse.org/u/AJ_Quick)
#### Post date: [September 14, 2026, 3:14am UTC](https://meta.discourse.org/t/advanced-google-analytics-v4/412327/1 "2026-09-14T03:14:19Z")

</div>

| | | |
| --- | --- | --- |
| ℹ | **Summary** | Advanced Google Analytics 4 event tracking for Discourse |
| 🛠 | **Repository Link** | [https://github.com/multidimension-al/discourse-google-analytics](https://github.com/multidimension-al/discourse-google-analytics) |
| 📖 | **Install Guide** | [How to install plugins in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157) |

Discourse core sends Google Analytics a single page\_view per navigation. This plugin adds events for reading time, reading progress and completion, and can optionally take ownership of page views so private message and admin routes are excluded.

#### _ **WHY NOT USE THE BUILT IN SEO/GA ANALYTICS TAG?** _

You can, and for a lot of forums it is enough. Core’s tag works, and this plugin runs on top of it rather than replacing it.

The difference is what gets measured. A page\_view tells you a URL was loaded. It cannot tell you whether anyone read what was on it, so a twenty minute read of a long topic and an instant bounce look identical in your reports. This plugin measures how long someone actually read, how far through the topic they got, and whether they reached the end. Those are the signals worth making content decisions on, and the ones that make a remarketing audience worth building.

Discourse’s own reports (Admin → Reports) are a separate system and stay the best place for internal metrics. This is only about what reaches Google Analytics.

### Features

- 13 community events: topic views, engagement and reading-progress milestones, read completion, per-visit summaries, search, registration, login, topic creation, replies, likes, bookmarks
- Reading measured against the post stream and attentive time, not scroll depth
- Two modes: extend core’s existing tag, or own the tag and page views
- Private messages, restricted categories and admin routes produce no event
- Topic titles and search terms off by default
- Staff traffic markable as GA4 internal traffic, by group
- Diagnostics page and admin dashboard warnings for misconfiguration

### Configuration

**1. Install**

```yml
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/multidimension-al/discourse-google-analytics.git

```

Then `./launcher rebuild app`.

**2. Pick a mode.** Admin → Settings → Google Analytics 4.

 ![image](https://global.discourse-cdn.com/meta/original/4X/9/b/7/9b781503d90c06727abb758bbf92aa41e0457bd9.png)

_Core Extension_ (default) — core keeps the tag and page views, the plugin adds events on top. Set core’s `ga universal tracking code` to your `G-XXXXXXXXXX` and `ga version` to `v4_gtag`.

_Managed_ — the plugin owns the tag and page views, which is what lets it exclude PM and admin routes. Clear core’s `ga universal tracking code`, set `ga4 integration mode` to `managed`, and put your ID in `ga4 measurement id`.

**3. Turn on `discourse ga4 enabled`.**

**4. Optional — internal traffic.** `ga4 internal traffic groups` defaults to admins and moderators. It only takes effect once you create the matching filter in GA4 under Admin → Data settings → Data filters → Internal traffic, matching `traffic_type` equals `internal`.

**5. Verify.** Admin → Plugins → Google Analytics → Diagnostics.

 ![image](https://global.discourse-cdn.com/meta/original/4X/d/a/1/da188179339501750d653dacb6461640a4602227.png)

To move an existing setup from Core Extension to Managed, use **Adopt existing Discourse GA configuration** on the Diagnostics page rather than editing settings by hand.

Settings

| Name | Description |
| --- | --- |
| `discourse ga4 enabled` | Enable the plugin. Off by default. |
| `ga4 integration mode` | `core_extension` (core owns the tag) or `managed` (the plugin owns it). |
| `ga4 measurement id` | GA4 Measurement ID, for managed mode. |
| `ga4 track page views` | Send `page_view`. Managed mode only. |
| `ga4 track topic views` | Send `discourse_topic_view` once per topic visit. |
| `ga4 track topic engagement` | Send `discourse_topic_engaged` at reading-time milestones. |
| `ga4 engagement milestones` | Seconds of active reading at which to fire. Default `10|30|60|180`. |
| `ga4 track topic progress` | Send `discourse_topic_progress` at reading-position milestones. |
| `ga4 progress milestones` | Percentages of the topic at which to fire. Default `25|50|75|100`. |
| `ga4 track read completion` | Send `discourse_topic_read_complete` when a reader reaches the end. |
| `ga4 read complete min seconds` | Minimum reading time before the end counts as completion. |
| `ga4 track read summaries` | Send `discourse_topic_read_summary` when a reader leaves a topic. |
| `ga4 read summary min seconds` | Below this, a visit is treated as a bounce and not summarised. |
| `ga4 track search` | Send `search` when a full-page search returns results. |
| `ga4 track registration` | Send `sign_up` after an account is created. |
| `ga4 track login` | Send `login` after a successful sign-in. Off by default. |
| `ga4 track topic creation` | Send `discourse_topic_created`. |
| `ga4 track replies` | Send `discourse_reply_created`. |
| `ga4 track likes` | Send `discourse_post_liked`. Removing a like sends nothing. |
| `ga4 track bookmarks` | Send `discourse_bookmark_created`. |
| `ga4 send search terms` | Also send what was searched for. Off by default — forum searches often contain personal information. |
| `ga4 send page titles` | Include the page title. Off by default — on a topic route this is the topic title. |
| `ga4 track private message activity` | One aggregate PM event carrying no identifiers. Off by default. |
| `ga4 login required is restricted` | On a login-required forum, withhold topic and category identifiers. |
| `ga4 send trust level` | Include trust level 0–4 as an event parameter. |
| `ga4 internal traffic groups` | Members of these groups are marked `traffic_type=internal`. Default: admins, moderators. |
| `ga4 suppress in embed` | Send nothing in embed mode. |
| `ga4 debug mode` | Log events and suppression decisions to the browser console. |

## Notes

- In Core Extension mode core still owns page views, so PM URLs and topic titles are still sent. Only Managed mode changes that.
- Don’t register `topic_id` as a GA4 custom dimension — it’s unbounded and will hit the property’s cardinality limits.
- Discourse’s own Admin → Reports → Trending Search records click-through, so it tells you which searches failed. GA4 can’t. That’s why `ga4 send search terms` is off by default.

Full write up and additional details are available on my website:

> **[Google Analytics Plugin for Discourse](https://www.ajquick.com/articles/google-analytics-plugin-for-discourse)**
>
> Set up Google Analytics 4 on Discourse with your Measurement ID, check that tracking works, and add optional reading and participation events with a plugin.

There’s a companion [Meta Pixel and Conversions API plugin](https://meta.discourse.org/t/meta-pixel-conversions-api/412405) built the same way.
