SOLVED

Re: Trying to Track Clicks on a Marketo Landing Page

Go to solution
Anonymous
Not applicable
Hi,

I am trying to track clicks on a Marketo landing page. One link is below an embedded slide deck however I am not sure if Munchkin code has been placed on the third party page where that slide deck is hosted.

Also want to track any clicks on an embedded Google Slide and Vimeo video. What steps do I need to take to ensure we can track clicks on the Marketo landing page?
Tags (1)
1 ACCEPTED SOLUTION
SanfordWhiteman
Level 10 - Community Moderator
Here's sample code that tracks YouTube events (Play, Pause, Play Until End) using Munchkin.  Adapted from YT's guide here.
 
<!-- 1. this DIV is replaced by the player IFRAME -->
<div id="player"></div>
<script>
  // 2. This code loads the IFrame Player API code asynchronously.
  var tag = document.createElement('script');

  tag.src = "https://www.youtube.com/iframe_api";
  document.getElementsByTagName('head')[0].appendChild(tag);

  // 3. This function creates an <iframe> (and YouTube player)
  //    after the API code downloads.
  var player, videoId = 'M7lc1UVf-VE';
  function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
      height: '390',
      width: '640',
      videoId: videoId,
      events: {
        'onStateChange': onPlayerStateChange
      }
    });
  }

  // 4. The API calls this function when the player's state changes.
  function onPlayerStateChange(event) {
    switch( event.data ) {
    case YT.PlayerState.PLAYING:
        Munchkin.munchkinFunction('visitWebPage', {
            url: 'https://youtube.com/'+videoId
           ,params: 'movie-action=pressed-play'
           }
        );
        break;
    case YT.PlayerState.PAUSED:
        Munchkin.munchkinFunction('visitWebPage', {
            url: 'https://youtube.com/'+videoId
           ,params: 'movie-action=paused'
           }
        );
        break;
    case YT.PlayerState.ENDED:
        Munchkin.munchkinFunction('visitWebPage', {
            url: 'https://youtube.com/'+videoId
           ,params: 'movie-action=played-til-end'
           }
        );
        break;
     }

  }
</script>

Of course you probably don't care about multiple Play events and likely don't care about Pause. Play Until End is significant -- but the catch is that the lead could pause 1 sec. before the end and you'd just see a Pause.

View solution in original post

25 REPLIES 25
Anonymous
Not applicable
@ Sanford, that is sweet, thanks for sharing that!

Yes one benefit of the Vidyard integration is that you see the incremental activities with percentages, so "Watched 50%", "Watched 75%", etc. 
SanfordWhiteman
Level 10 - Community Moderator
Here's sample code that tracks YouTube events (Play, Pause, Play Until End) using Munchkin.  Adapted from YT's guide here.
 
<!-- 1. this DIV is replaced by the player IFRAME -->
<div id="player"></div>
<script>
  // 2. This code loads the IFrame Player API code asynchronously.
  var tag = document.createElement('script');

  tag.src = "https://www.youtube.com/iframe_api";
  document.getElementsByTagName('head')[0].appendChild(tag);

  // 3. This function creates an <iframe> (and YouTube player)
  //    after the API code downloads.
  var player, videoId = 'M7lc1UVf-VE';
  function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
      height: '390',
      width: '640',
      videoId: videoId,
      events: {
        'onStateChange': onPlayerStateChange
      }
    });
  }

  // 4. The API calls this function when the player's state changes.
  function onPlayerStateChange(event) {
    switch( event.data ) {
    case YT.PlayerState.PLAYING:
        Munchkin.munchkinFunction('visitWebPage', {
            url: 'https://youtube.com/'+videoId
           ,params: 'movie-action=pressed-play'
           }
        );
        break;
    case YT.PlayerState.PAUSED:
        Munchkin.munchkinFunction('visitWebPage', {
            url: 'https://youtube.com/'+videoId
           ,params: 'movie-action=paused'
           }
        );
        break;
    case YT.PlayerState.ENDED:
        Munchkin.munchkinFunction('visitWebPage', {
            url: 'https://youtube.com/'+videoId
           ,params: 'movie-action=played-til-end'
           }
        );
        break;
     }

  }
</script>

Of course you probably don't care about multiple Play events and likely don't care about Pause. Play Until End is significant -- but the catch is that the lead could pause 1 sec. before the end and you'd just see a Pause.
Derek_Hays1
Level 1

The code referenced here by @SanfordWhiteman as well as the YouTube code works great on a standard HTML page. But when I pull it into the Custom HTML for Known people it does not work. Can't figure out why. Any ideas? what am I missing?

SanfordWhiteman
Level 10 - Community Moderator

You'll have to provide a URL.

Derek_Hays1
Level 1

@SanfordWhiteman Here's a test version of the form/page in question. Lots of videos on this page. But when I scaled it back to just the examples in this string (e.g. your code, and the YouTube API example), the behavior was still the same . The behavior is this: If you complete form, the content (page and videos) load without problem from the WP site. But if you return to the page (Known Visitor), the page loads minus the videos. It is the same code in both places, hence my question does the MKTO Known Visitor page process JavaScript differently? Thanks. 

SanfordWhiteman
Level 10 - Community Moderator

do see your custom video tracking hits, though, when the videos are in the KV HTML area:

 

2020-05-09 16_18_18-CodePen - SaltStack-MktoForms2 __ YT tracker.png

 

(That's a very aggressive use of KV HTML! Don't think I've ever packed that much HTML into the space, nothing inherently wrong with it but it increases the size of the form descriptor a ton — would be more efficient to have that HTML hidden lazy-loaded somewhere else on the page and then inject it into the KV HTML, so it wouldn't affect load time when the session isn't yet known. But that's off-topic.)

Derek_Hays1
Level 1

@SanfordWhiteman Thanks for your response. I agree that there's a lot in that page and like your efficiency suggestion. I will look at that. 

Any ideas on why the Known Visitor page would not load the videos though? Even when I scale that page back to just two videos, I can't get them to load. I had this loading process working for 5 months, then the form got updated, the video stopped loading, and I'm at a loss to why. 

SanfordWhiteman
Level 10 - Community Moderator

I'm saying it does load and track the videos for me.

Derek_Hays1
Level 1

I'm glad you can see them. But also perplexed. As I cannot.  


I did some more testing. If I take the video loading/tracking javascript out of the WP landing page then the videos load fine in the known visitor page. But I can no longer see them on the form completion page. If I leave the video loading/tracking javascript in the WP landing page then the videos load upon form completion but not when I return to page as a known visitor. 

 

I believe the issue is not with the javascript used for loading and tracking the videos. Instead the conflict seems to be come displaying the videos from both the WordPress landing page (form successfully completed) and from the Known Visitor (Marketo) pages.

 

I believe the issue is related to the "visible/hidden" javascript that hides the landing page content/videos until after the form has been submitted. While this approach does hide the content (including videos) until the form is completed, it still loads the content in the background.

 

So when a returning visitor comes to the landing page, the same content (including video loading/tracking javascript elements) are getting loaded twice once from the WordPress landing page (hidden), and a second time from the MKTO known visitor page (visible). And this somehow causes a conflict that keeps the videos from loading.

This is my best take at the moment. I don't have solution worked out yet. Thanks. 

Anonymous
Not applicable

I've encountered problem using this code  - it is not responsive , any ideas on how to make it fully responsive?

Jason_Hamilton1
Level 8 - Champion Alumni

Sanford Whiteman​ this looks great, is it possible to have multiple videos on the page with this type of tracking?

SanfordWhiteman
Level 10 - Community Moderator

Sure, just create a YT.Player for each video. You would want to avoid duplicate variable names, too -- probably use an array of video IDs, etc.

BTW the latest code is at MktoMunchkin :: YouTube Player API - JSFiddle

Diego_Lineros2
Level 7

No so quick... I did try with more than one video the code below and I've got inconsistent tracking. So I did add alerts, put in a fiddle and in Marketo. The fiddle works well but live in Marketo doesn't. I got better results in FF.

Any ideas?

<div id="player1"></div>

<div id="player2"></div>

<script>

    var tag = document.createElement('script');

      tag.src = "https://www.youtube.com/iframe_api";

      var firstScriptTag = document.getElementsByTagName('script')[0];

      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);    

      var player1;

      var player2;

      var videoId1 = "D_VRSFpUcp0";

      var videoId2 = "ncvFAm4kYCo";

  function onYouTubeIframeAPIReady() {

    player1 = new YT.Player('player1', {

    videoId: 'D_VRSFpUcp0',

    events: {

        'onStateChange': onPlayerStateChange1

                       }

    });

   

      player2 = new YT.Player('player2', {

    videoId: 'ncvFAm4kYCo',

    events: {

           'onStateChange': onPlayerStateChange2

                       }

    });

    }

   

   function onPlayerStateChange1(event) {

     switch( event.data ) {     

    case YT.PlayerState.PLAYING:

    alert(videoId1);   

    Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+videoId1

            ,params: 'movie-action=pressed-play'

           }

        );

  

    case YT.PlayerState.PAUSED:

             Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+videoId1

           ,params: 'movie-action=paused'

           }

        );

     

    case YT.PlayerState.ENDED:

             Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+videoId1

            ,params: 'movie-action=played-til-end'

           }

        );

     

     }

  }

function onPlayerStateChange2(event) {

      switch( event.data ) {

   case YT.PlayerState.PLAYING:

    alert(videoId2);

        Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+videoId2

            ,params: 'movie-action=pressed-play'

           }

        );

       

    case YT.PlayerState.PAUSED:

   

        Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+videoId2

           ,params: 'movie-action=paused'

           }

        );

    

    case YT.PlayerState.ENDED:

    

        Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+videoId2

            ,params: 'movie-action=played-til-end'

           }

        );

    

     }

  }

 

</script>

SanfordWhiteman
Level 10 - Community Moderator

I'm going to need more details about "inconsistent."  But first, you must simplify your code.  There's no reason to have different state change event listeners.  The Video ID is always available as event.target.getVideoData().video_id.  So just have one listener function.

Diego_Lineros2
Level 7

This is a version with only one listener, the story is that the second player is not firing the event in Marketo. It does in the fiddle Edit fiddle - JSFiddle

<div id="player1"></div>

<div id="player2"></div>

<script>

    

    var tag = document.createElement('script');

      tag.src = "https://www.youtube.com/iframe_api";

      var firstScriptTag = document.getElementsByTagName('script')[0];

      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);   

      var palyer1, player2;

      function onYouTubeIframeAPIReady() {

    player1 = new YT.Player('player1', {

    videoId: 'D_VRSFpUcp0',

    events: {

        'onStateChange': onPlayerStateChange

                       }

    });

  

      player2 = new YT.Player('player2', {

    videoId: 'ncvFAm4kYCo',

    events: {

           'onStateChange': onPlayerStateChange

                       }

    });

    }

  

   function onPlayerStateChange(event) {

    vid = event.target.getVideoData().video_id;

    switch( event.data ) {

    case YT.PlayerState.PLAYING:

    alert(vid);  

    Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+vid

            ,params: 'movie-action=pressed-play'

           }

        );

  break;

    case YT.PlayerState.PAUSED:

             Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+vid

           ,params: 'movie-action=paused'

           }

        );

    break;

    case YT.PlayerState.ENDED:

             Munchkin.munchkinFunction('visitWebPage', {

            url: 'https://youtube.com/'+vid

            ,params: 'movie-action=played-til-end'

           }

        );

     break;

     }

  }

</script>

Diego_Lineros2
Level 7

I found the issue, My Jquery library was 1.7, updated to 2.1.3 and all working

SanfordWhiteman
Level 10 - Community Moderator
In order to track views/clicks within embedded pages (IFRAMEs), either:

[a] the IFRAME needs to load Munchkin.js

or

[b] the IFRAME needs to have code to communicate with Munchkin on the outer page (probably via HTML5 Web Messaging)

If you have neither of these, then you'll only be tracking the views/clicks on the outer page (which could potentially include an initial click that embeds the IFRAME, for example by replacing a placeholder image, but still it won't include navigation within the IFRAME).
Anonymous
Not applicable
If it is a standard link on your landing page, it should be tracked automatically. (An exception is if the link is inside a plain text token which are not tracked). 

If you are trying to track interactions with an embedded element like slides or a video, it can be a bit trickier. 

One method, if you can apply javascript to the container, is to create "virtual pageviews" by having the javascript simulate a visit to your domain on a URL that doesn't exist but which represents the click. 

E.g., pages.yourdomain.com/event-you-want-to-track.html

Then this would appear in the activity log and you could trigger and filter on it. 

Eric Hollebone used to have a useful guide for doing this step-by-step, but alas I think the page is down. But that is the gist. 

Alternatively for video you could use a provider like Wistia or Vidyard that integrates and will track these events for you automatically. I use Vidyard myself. Josh Hill published a detailed review: http://www.marketingrockstarguides.com/how-to-track-video-in-marketo-with-vidyard-1773/

Doesn't help you with the slides though. There may be a way for these but I haven't had to crack that nut before!
Josh_Hill13
Level 10 - Champion Alumni
You may not be able to track clicks on the embedded objects. Marketo offers a Clicks Link on Web Page filter, so try to see what options it gives you for the embedded link or for that page.

If you want to track those embedded items, you will need to add javascript of some type. Vidyard has a great integration to track your videos.
Anonymous
Not applicable

Hello,

How do I track links that are tracked on a Marketo Landing Page. I am playing around with the Smart List Filter 'Clicks Link on Web Page' but it  only pulls up links on our actual website and not from Marketo Landing pages.  How do i get the drop down menu to include these links?

Thank you