Announcements

Help Wizard

Step 1

NEXT STEP

FAQs

Please see below the most popular frequently asked questions.

Loading article...

Loading faqs...

VIEW ALL

Ongoing Issues

Please see below the current ongoing issues which are under investigation.

Loading issue...

Loading ongoing issues...

VIEW ALL

Spotify iFrame tracking via GTM. Any code?

Spotify iFrame tracking via GTM. Any code?

Hello Team,

 

I was trying to track Spotify embed on my website via gtm, I tried searching a lot on Google but didn't find any solution. Can you help me with a code to track Spotify's iframe on a website with GTM?

 

Thank you in advance

 

Tanuj

Reply
15 Replies

Howldy wop9825,

Sure! Here is a step-by-step guide to track Spotify embed on your website via GTM:

  • First, you need to create a new Tag in your Google Tag Manager account. Go to Tags > New > Tag, and select "Custom HTML" as the Tag type.

  • Copy and paste the following code snippet into the HTML field:

 

 

<script>
// Listen for the Spotify player to load
window.addEventListener('message', function(event) {
  if (event.origin === 'https://open.spotify.com') {
    // Spotify player is ready, send an event to Google Tag Manager
    dataLayer.push({
      event: 'spotifyReady',
      spotifyUri: event.data.uri
    });
  }
}, false);
</script>

 

 

  • Save the Tag and give it a descriptive name like "Spotify Embed Tracker".

  • Next, you need to create a new Trigger that fires when the Spotify player is ready. Go to Triggers > New > Trigger, and select "Custom Event" as the Trigger type.

  • In the "Event name" field, enter "spotifyReady".

  • Save the Trigger and give it a descriptive name like "Spotify Embed Ready".

  • Finally, you need to associate the new Tag and Trigger with your Spotify embed. To do this, go to your website and find the code for your Spotify embed.

  • Add the following code snippet to your Spotify embed code, replacing "YOUR-GTM-CONTAINER-ID" with the ID of your Google Tag Manager container:

 

<iframe src="https://open.spotify.com/embed/track/3qN5qMTKyEEmiTZD38CmPA" width="300" height="380" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>
<script>
// Send a message to the Spotify player to let it know our domain
var spotifyPlayer = document.querySelector('iframe[src^="https://open.spotify.com"]');
spotifyPlayer.contentWindow.postMessage({
  type: 'listeningOn',
  domain: window.location.hostname,
  gtmId: 'YOUR-GTM-CONTAINER-ID'
}, 'https://open.spotify.com');
</script>

 

 

  • Save the changes to your Spotify embed code and publish your website.

Now, whenever a user loads your website and interacts with the Spotify embed, an event will be sent to your Google Tag Manager account with the Spotify URI of the track that was played. You can use this information to create custom reports and track user behavior on your website.

I'll be barking up the wrong tree without updates on your situation!

 

-Prague the Dog

 

Hi Prague the Dog,

 

thanks for sharing. Unfortunately, it seems not to work for me. I try to track play on a podcast show, but there are no events coming up, when clicking the play button. Any ideas how to fix?

 

Cheers

Hi,

 

shouldn't the listener tag be triggered by "All Pages" instead of only when the "spotifyReady" event comes up? Otherwise, the "spotifyReady" event would never come up, or I'm mistaken?

 

When I integrate the tag on "All pages" and click on the play button, the event "spotifyReady" comes up every second.

 

Perhaps you described this step incorrectly in your tutorial?

 

Anyway, thank you very much for your effort!

 

Cheers

 

Did this ever start working for you? 

Are you able to track events properly?

No, not really as discribed in the tutorial. But with the tag been triggered by "All Pages“ it seems to work for what I want to archive. When I strictly stick with the tutorial an event would never come up for me.

This worked for me when I changed the trigger type, but I had to change the tag trigger to fire on "All Initialization Events" to get it to work.

I have the same problem that you? How did you fix it? Because if chenge the triggered by "All Pages“ i still with the same problem, the event "spotifyReady" comes up every second

Version 0.0.1:

 

So what I'm doing right now is

1. I printed 'event' to the console to see its parameters and found out the URI is not at 'event.data.uri' but at 'event.data.payload.playingURI';

2. I created a JS variable name 'spotifyLastURI';

2.1. This variable is then used to detect whether the URI has changed or was empty, so the dataLayer event will trigger only when the URI is different, because (as folks commented above) it kept triggering non-stop, and the problem was that it also wasn't bringing the valuable information (spotify's URI) for me.

<script>
spotifyLastURI = '';
window.addEventListener('message', function(event) {
  if (event.origin === 'https://open.spotify.com') {
    if (event.data.payload.playingURI && spotifyLastURI != event.data.payload.playingURI) {
      dataLayer.push({
        event: 'spotifyReady',
        spotifyUri: event.data.payload.playingURI
      });
      spotifyLastURI = event.data.payload.playingURI;
    }
  } 
}, false);
</script>

 

And now my 'spotifyReady' event actually brings something useful:

 

{
  event: "spotifyReady",
  gtm.uniqueEventId: 45,
  spotifyUri: "spotify:album:2hLNxoJZ5kZoBEX0XGBRNu"
}

 

The next step was to add a new DLV (dataLayer variable) in Google Tag Manager named 'spotifyUri' and used it as a parameter in a GA4 tag.

 

And I'm now able to register which Spotify's content was loaded dinamically in my website, which is a good working point. I'd love to actually register which Artist, Song, Album, Playlist or Episode was loaded since it's possible that content may be removed in the future and I'll never know what it actually was because I won't be able to visit the link. But it solves most people's problems, I guess!

It works very nice. And you can monitor via GA4's Realtime report.


Events' card (GA4 Realtime):

spotify-ga4-01.png

 

GTM - GA4 tag for Spotify Content:

spotify-ga4-02.png

I updated some outdated references and added a variable to allow the dataLayer event to be triggered only once for each new content loaded into the player.

Version 0.0.2:

 

For a more robust implementation and to be able to detect multiple events as the content is played:

- audio_playback_started;

- audio_playback_paused;

- audio_playback_resumed;

- audio_complete;

- audio_progress (with configurable detection values' array i.e. [25, 50, 75]);

 

 

Parameters:

- audio_content;

audio_content_type;

- audio_current_time;

- audio_duration;

- audio_percent;

- audio_provider;

- audio_status;

- audio_url.

 

GTM Custom HTML Spotify Audio Tag:

<script>
(function spotifyAudioListenerTag() {
  // - Edit the list below to setup Progress events detected
  // percentage values:
  var spotifyPercentagesToBeDetected = [
    10, 20, 30, 40, 50, 60, 70, 80, 90, 99
  ]
  // - The operation below is needed to assure the list of
  // percentages to be detected as progress events follow
  // the correct format.
  spotifyPercentagesToBeDetected = (function(arr) {
    var onlyNumsTruncatedList = arr.filter(function(element) {
      return typeof element === 'number';
    }).map(function(element) {
      return Math.trunc(element);
    }).filter(function(element) {
      return element > 0 && element < 100;
    });
    var uniqueValuesObject = {};
    for (var i = 0; i < onlyNumsTruncatedList.length; i++) {
      uniqueValuesObject[onlyNumsTruncatedList[i]] = true;
    }
    var uniqueList = Object.keys(uniqueValuesObject).map(function(key) {
      return parseInt(key, 10);
    });
    uniqueList.sort(function(a, b) {
      return a - b;
    });
    return uniqueList;
  })(spotifyPercentagesToBeDetected);

  // - Check if a calculated percentage value should or
  // not be detected.
  function shouldPercentageBeDetected(percent, detectionList) {
    for (var i = 0; i < detectionList.length; i++) {
      if (percent >= detectionList[i] && !(detectionList[i+1] && detectionList[i+1] <= percent)) {
        return { check: true, value: detectionList[i] };
      }
    }
    return { check: false, value: undefined };
  }

  var spotifyWasPaused = false;
  var spotifyAudioCompleted = false;
  var spotifyRegisteredProgress = [];
  var spotifyLastDuration = 0.0;
  var spotifyLastURI = '';
  window.addEventListener('message', function(event) {
    if (event.origin === 'https://open.spotify.com') {
      var audioPercent = Math.trunc((event.data.payload.position / event.data.payload.duration) * 100) || 0;
      var audioCurrentTime = (event.data.payload.position / 1000) || 0;
      var audioDuration = (event.data.payload.duration / 1000) || 0;
      var spotifyURI = event.data.payload.playingURI;
      var reSpotifyUri = /spotify:([^:]+):([^:]+)/i;
      var audioData = (function(uri) {
        var result = { contentType: '', url: '' };
        if (reSpotifyUri.test(uri)) {
          var parts = reSpotifyUri.exec(uri);
          result.contentType = parts && parts[1];
          result.url = parts && 'https://open.spotify.com/'+parts[1]+'/'+parts[2];
        }
        return result;
      })(spotifyURI);
      var spotifyEvent = {
        event: 'spotifyEvent',
        audioPercent: audioPercent,
        audioCurrentTime: audioCurrentTime,
        audioDuration: audioDuration,
        audioContentType: audioData.contentType,
        audioUrl: audioData.url,
        spotifyURI: spotifyURI
      }
      // - Restart Playback Control Variables in case URI ou Duration has
      // changed (track change detection within playlist, album or artist).
      if ((spotifyURI && spotifyURI !== spotifyLastURI) || (spotifyURI && spotifyURI === spotifyLastURI && spotifyLastDuration !== audioDuration && spotifyLastDuration && audioDuration && Math.round(spotifyLastDuration) !== Math.round(audioDuration))) {
        spotifyAudioCompleted = false;
        spotifyWasPaused = false;
        spotifyRegisteredProgress = [];
      }
      // 1. Progress Events
      if (spotifyURI && shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).check) {
        if (!spotifyRegisteredProgress.includes(shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value)) {
          spotifyRegisteredProgress.push(shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value);
          spotifyEvent.audioStatus = 'progress';
          spotifyEvent.audioPercent = shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value;
          dataLayer.push(spotifyEvent);
          spotifyLastURI = spotifyURI;
          if (audioDuration) spotifyLastDuration = audioDuration;
        }
      }
      // 2. Playback updates
      // 2.1. Playback Start
      if (spotifyURI && event.data.type === 'playback_started') {
        spotifyEvent.audioStatus = 'playback_started';
        dataLayer.push(spotifyEvent);
        spotifyLastURI = spotifyURI;
      // 2.2. Playback Paused
      } else if (spotifyURI && event.data.type === 'playback_update' && event.data.payload.isPaused && audioCurrentTime && !spotifyWasPaused) {
        spotifyEvent.audioStatus = 'playback_paused';
        dataLayer.push(spotifyEvent);
        spotifyLastURI = spotifyURI;
        if (audioDuration) spotifyLastDuration = audioDuration;
        spotifyWasPaused = true;
      // 2.3. Playback Resumed
      } else if (spotifyURI && event.data.type === 'playback_update' && !event.data.payload.isPaused && spotifyWasPaused && event.data.payload.position) {
        spotifyEvent.audioStatus = 'playback_resumed';
        dataLayer.push(spotifyEvent);
        spotifyLastURI = spotifyURI;
        if (audioDuration) spotifyLastDuration = audioDuration;
        spotifyWasPaused = false;
      // 2.4. Complete
      } else if (spotifyURI && event.data.type === 'playback_update' && audioDuration === audioCurrentTime && !spotifyAudioCompleted) {
        spotifyEvent.audioStatus = 'complete';
        spotifyEvent.audioPercent = 100;
        dataLayer.push(spotifyEvent);
        spotifyLastURI = spotifyURI;
        if (audioDuration) spotifyLastDuration = audioDuration;
        spotifyAudioCompleted = true;
      }
    }
  }, false);
})();
</script>

 

GTM GA4 Tag:

tomasfn87_1-1747188200616.png

 

GTM GA4 Spotify Event Trigger:

tomasfn87_2-1746702012964.png

 

GTM Folder:

tomasfn87_2-1747188253461.png

 

DataLayer events for a Spotify Episode: playback_started (6), progress (from 7 to 16; from 18 to 25) and complete (17) events:

tomasfn87_0-1747197568384.png

 

 To log Spotify's player activity to the console:

(check if this is working before anything)

 

window.addEventListener(
  'message',
  function(e) {
    console.log(e);
  },
  false
);

 

 

 

Hey JoannaReyes, please try my freshly developed solution (described under Version 0.0.2). It's a complete Spotify Audio Tag, similar to YouTube and Vimeo Video Tags.

 

The repository link cannot be shared but it's Microsoft's repository service, you just need to add the path below:

/tomasfn87/url-parser/blob/main/gtm/spotify-audio.json.md

Suggested posts