Spotify tracking in Google Tag Manager
New in 2.0.0. Google Tag Manager for WordPress reports how your visitors listen to the Spotify tracks, episodes and playlists embedded on your site. Starting, pausing, buffering and reaching the end become data layer events that you can use as triggers in Google Tag Manager.
This page describes GTM4WP 2.0.0 and newer. Spotify tracking did not exist in the legacy 1.x versions of the plugin.
The option is experimental and carries an Experimental badge in the plugin settings. Spotify reports much less about playback than the other players do, and the states the plugin reports are worked out from what little the embed exposes. Read the section on derived states below before you rely on the numbers.
Turning Spotify tracking on
Open the plugin settings, go to the Media events section, expand the Media players group and check Spotify events. The option is switched off by default.
Which embeds are detected
The tracker wires every iframe whose src contains open.spotify.com/embed. That covers the embed code you copy from Spotify and a Spotify link pasted on its own line, which WordPress turns into the same player.
Tracking depends on the Spotify iFrame API, which is only requested once the tracker has actually found a Spotify embed on the page, so a page without one never contacts Spotify. If a consent manager, an ad blocker or a network error keeps that script from loading, nothing is pushed and nothing breaks on your page.
The Spotify API hands control to a single global callback when it loads. If another integration on your site has already claimed that callback, the plugin calls it first and then does its own work, so both keep running.
A player that is in the page when it loads is wired straight away. One inserted later, for example in a popup, a lightbox or a section loaded by AJAX, needs the Track dynamically inserted players option in the Advanced group as well.
Every state is derived, not reported
This is what makes Spotify different from every other player here, and it is worth understanding before you build a trigger.
The Spotify embed fires no play event, no pause event and no finished event. It sends one repeating update instead, a few times a second, carrying the current position, the total length, whether playback is paused and whether it is buffering. The plugin turns that stream of updates into the familiar states and pushes one only when the state has actually changed, so you get a single play rather than dozens.
| mediaPlayerState | How it is worked out |
|---|---|
buffering | The update says the player is buffering. |
ended | The position has reached 99 percent of the total length. |
pause | The update says the player is paused. |
play | None of the above, so playback is running. |
The 99 percent rule is the part to watch. A listener who stops one or two seconds before the real end of a long track never reaches it, and a listener who skips to the last few seconds triggers it without having heard the track. Treat ended here as a close approximation rather than a fact.
There is also no seek signal, so jumping around inside a track produces no seeked state.
Where the title comes from
The Spotify player itself reports no title, so the plugin finds one another way.
In the normal case it reads the title attribute of the embed on your page. Spotify writes that attribute into the embed code it hands WordPress, in the form Spotify Embed: Never Gonna Give You Up, and the plugin strips the prefix and keeps the name. This costs nothing and is available immediately, so the very first event already carries a real title. An embed you wrote by hand with a title of its own is used as it stands.
When an embed carries no title attribute, the plugin asks Spotify’s public oEmbed endpoint once, without sending any cookies. The answer is remembered for the rest of the page. Nothing waits for it: the request goes out as the embed is wired, a whole player load before anything can be pushed, so in practice it has landed by the time the first event fires. Deferring events on it would risk losing them entirely if a consent manager left the request hanging.
A playlist or album embed is a special case worth knowing about. The embed markup describes the playlist, but each track that starts playing is a different item with a different name, so the plugin looks those up as they come and reports the track rather than the playlist.
If none of that produces a name, the title falls back to the Spotify URI, for example spotify:track:4cOdK2wGLETKBW3PvgPWqT. A failed lookup is remembered as a failure so it is not retried, because the playback update that triggers it repeats several times a second.
Player events
Spotify is the only supported player that never fires gtm4wp.mediaPlayerEvent. The embed exposes no volume, quality, rate or error signal, so there is nothing to report. A trigger built on that event will never fire for Spotify.
What mediaData holds for a Spotify item
| Variable | Contents |
|---|---|
mediaData.id | The Spotify ID of the track, episode or playlist. |
mediaData.author | Always empty. The embed exposes no artist or show name. |
mediaData.title | The name of the item, resolved as described above, or the Spotify URI when nothing could be resolved. |
mediaData.url | The public Spotify address, for example https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT. |
mediaData.duration | The length in seconds. Spotify reports milliseconds and the plugin converts them. |
The mediaType variable is spotify in every event.
The gtm4wp.mediaPlayerReady event is pushed as soon as the player is ready, before any update has arrived, so its duration is 0.
Google Tag Manager built-in Video variables
Every Spotify media event also populates the built-in Video variables of Google Tag Manager, with Video Provider set to spotify. The section on built-in Video variables explains how to enable and use them. They are named for video, but they work the same way for audio.
Video Visible is measured on the player as it stands on the page. The Spotify API swaps the embed for one of its own while it sets up, and the plugin follows that swap, so the measurement always refers to the player the visitor can actually see.
Building a trigger in Google Tag Manager
To fire a tag when a visitor starts a Spotify track:
- Create a Data Layer Variable named
mediaPlayerState. - Create a Custom Event trigger whose event name is
gtm4wp.mediaPlayerStateChange. - Add the condition
mediaPlayerStateequalsplayto the trigger. - Attach the trigger to your tag. To send the name of the item along with it, create a second Data Layer Variable named
mediaData.title.
To measure progress instead, build the trigger on gtm4wp.mediaPlaybackPercentage and add a condition on mediaPercentage. Progress is the more trustworthy measure for this player, given how ended is worked out.
Limitations
- Nothing is reported directly. Every state is worked out from a repeating position update, so the states are as good as that inference and no better.
endedmeans the position passed 99 percent of the length, not that the item genuinely finished.- There is no
seekedstate. gtm4wp.mediaPlayerEventnever fires for Spotify.mediaData.authoris always empty, and the title falls back to the Spotify URI when the embed carries no title and the lookup does not answer.- The ready event reports a duration of 0, because no update has arrived at that point.
- There is no 100 percent milestone. See playback percentage milestones.
Related pages
The overview of media player tracking describes the events, data layer variables and playback milestones that every player shares. See also the two other audio players, SoundCloud and Mixcloud.

