Tracking audio listens in Google Analytics 4 or Matomo: what the player sends, and how to catch it
The audio player reports every listen to your own analytics, through the dataLayer and a page event. The exact event list, the setup in Tag Manager, GA4 and Matomo, and why your numbers will never quite match ours.
Most newsrooms already have one place where the numbers live. It might be Google Analytics 4, Matomo or Piano, but that is where Monday's meeting happens and where sections get compared. A metric that sits in a separate dashboard, however carefully built, tends to stop being opened after a month.
Our client area has its own listening screen, and we think it is a good one. But we also built the player so that listens land in your analytics, without you having to ask us for an export. This piece lists exactly what the player sends, how to wire it up, and what it deliberately leaves out.
What the player tells the page it sits on
When the player is mounted by our script (which is what the WordPress plugin and the copy-paste snippet both do), every listening event is relayed to the host page in two ways at once:
- a
dataLayerentry, if the page has a dataLayer, which is the case as soon as Google Tag Manager is installed. The event name is prefixed withwedispatch_and carries a single parameter,wedispatch_article, the audio's identifier; - a page event called
wedispatch, fired ondocument, whose detail holdsevent(the type) andarticle(the identifier). This one is for every other tool.
Here is the full list of types as written in the code. There are no others:
| Event | What happened |
|---|---|
| wedispatch_listen | playback of the full article started |
| wedispatch_listen_25, _50, _75, _100 | the listener reached a quarter, half, three quarters, the end |
| wedispatch_listen_preview | a preview clip played, because the article is locked |
| wedispatch_gate_shown | the sign-up wall was displayed |
| wedispatch_gate_click | the listener clicked its button |
| wedispatch_preroll_played, wedispatch_midroll_played | an audio ad played, before or during the article |
Each event fires once per page load. Someone who pauses and resumes ten times is one listen, not ten, and a milestone crossed twice after scrubbing back is still counted once.
With Google Tag Manager and GA4
This is the shortest route, because the dataLayer is precisely what Tag Manager reads. You need three things:
- a trigger of type "Custom Event", with the event name set to the regular expression
^wedispatch_(or justwedispatch_listenif you only care about starts); - a variable of type "Data Layer Variable", named
wedispatch_article; - a tag of type "Google Analytics: GA4 Event", using the built-in
{{Event}}variable as its event name and anarticleparameter filled by the variable above.
One more step in GA4 itself: an event parameter only shows up in reports once it is registered as an event-scoped custom dimension. Skip it and you will see your listens without knowing which audio they belong to. Page title and URL are added by your own GA4 tag, since it is your page.
If your site only loads gtag.js, with no Tag Manager, dataLayer entries do not turn into report events on their own. Use the page event instead:
````
document.addEventListener("wedispatch", function (e) {
gtag("event", "wedispatch_" + e.detail.event, { article: e.detail.article });
});
With Matomo, Piano or anything else
Same idea, one extra line. For Matomo:
````
document.addEventListener("wedispatch", function (e) {
_paq.push(["trackEvent", "Audio", e.detail.event, e.detail.article]);
});
The "Audio" category groups everything, the action says what happened (listen, listen_50 and so on), and the name carries the audio identifier. Piano and other tools all have an equivalent call: the listener stays the same, only the last line changes.
What we do not send, and why
The relay passes two facts: the event type and the audio identifier. Not the page address, not the title, nothing about the listener. That is a design decision rather than a gap. Your tool knows which page it is on and is the one that handles your visitors' consent, so we hand it the fact and it records it under its rules. If a visitor declines audience measurement and your tool never loads, the event fires into nothing and nothing is sent anywhere else. What the player stores on a visitor's device, and what it does not, is covered in our piece on cookies and consent.
Two situations never emit anything: the preview you hear while configuring the player, and listens from inside your client area. An editor who replays their settings ten times should not inflate their own completion rate, in our numbers or in yours.
Why your numbers and ours will not match
Put your GA4 report next to our listening analytics and you will see a gap. That is expected, and the causes are known:
- consent: your tool only counts visitors who accepted it, while our anonymous counter does not depend on that choice;
- blockers: blocklists go after well-known analytics tools first, which cuts off your Tag Manager or Matomo without necessarily touching our counter;
- how the player is mounted: a player dropped in as a bare frame, without our script, has nobody to relay its events to the page.
So use each source for what it is good at. Ours gives the most complete volume and per-audio completion. Yours knows what ours cannot: where the visitor came from, what they read before, whether they subscribed afterwards. Audio earns its budget when listens are crossed with your own conversions, which is exactly why the event needs to reach you. Once the data is flowing, our guide to what to actually measure helps sort the useful metrics from the flattering ones.
Give your articles a voice with WeDispatch
This blog is itself voiced by WeDispatch. Curious how it sounds on your content?
Book a demo