How-to

Track YouTube, Calendly, Typeform & HubSpot Embeds with GTM

Track YouTube, Calendly, Typeform & HubSpot Embeds with GTMiframe — GTM can't read insideYouTube · Calendly · TypeformpostMessagelisten → pushdataLayer.push(event: 'booking' )

Embeds (YouTube videos, Calendly bookings, Typeform surveys, HubSpot forms) are some of the most valuable interactions on a site, and some of the hardest to track. They run in someone else's iframe, so GTM can't see inside them. The trick is to listen for the messages each embed sends out. Here's the pattern, and how the popular ones work.

Why embeds are hard to track

An embed lives in a cross-origin <iframe>. Your GTM container can't read its DOM or its clicks, browser security forbids it. So you can't watch a Calendly booking the way you'd watch a button. Instead, most embeds emit events (usually via postMessage or their own JS SDK) that the parent page can listen for.

The universal pattern

For almost every embed it's the same three moves: listen for the embed's event, read what you need from it, and push a clean event to the dataLayer that your GTM trigger matches.

YouTube, the easy one

YouTube is the rare embed GTM handles natively. Enable the built-in YouTube Video trigger and GTM listens for play, pause, progress and complete with no custom code, as long as the embed allows the JS API. Fire a GA4 video_start / video_complete event off it.

Calendly, Typeform & friends, postMessage

Most embeds without a built-in trigger broadcast events via postMessage. You add a small listener (a Custom HTML tag) that filters for that embed's messages and pushes to the dataLayer.

// Listen for Calendly's postMessage events and forward to GTM
window.addEventListener('message', (e) => {
  if (e.data?.event && String(e.data.event).startsWith('calendly')) {
    if (e.data.event === 'calendly.event_scheduled') {
      window.dataLayer.push({ event: 'calendly_booking' });
    }
  }
});

Then a Custom Event trigger for calendly_booking fires your GA4 (and Google Ads) conversion. Typeform, Wistia and others follow the same shape, only the message names change.

HubSpot, Vimeo, SDK callbacks

Some embeds give you a JavaScript callback instead of raw messages. HubSpot forms expose onFormSubmitted; Vimeo and Wistia have player SDKs with play / ended events. You bind to the callback and push to the dataLayer, same idea, friendlier API.

// HubSpot form callback → dataLayer
window.addEventListener('message', (e) => {
  if (e.data?.type === 'hsFormCallback' && e.data.eventName === 'onFormSubmitted') {
    window.dataLayer.push({ event: 'hubspot_form_submit', form_id: e.data.id });
  }
});

Practice this on a real container

Each embed is the same listen-read-push pattern with different event names. Practice capturing YouTube, Calendly and HubSpot events into the dataLayer on live embeds, debugged in Tag Assistant.

Practice embed listeners →

Gotchas

  • Check the origin. Validate e.origin in your listener so you only act on the real embed's messages.
  • Enable the JS API. YouTube needs enablejsapi=1; some embeds need a setting toggled to emit events.
  • Don't double-count conversions. A booking or form submit is often a conversion, give it a stable id and fire once.
  • Embeds can load late. Attach listeners early so you don't miss the first events.

Now go practice it

Reading sticks when you do it. These hands-on lessons load your own GTM container and let you debug in Tag Assistant.

Frequently asked questions

How do I track embeds like Calendly or Typeform in GTM?

Embeds run in a cross-origin iframe GTM can't read, so you listen for the events they emit. Add a listener (a Custom HTML tag) that filters for the embed's postMessage events, read what you need, and push a clean event to the dataLayer (for example calendly_booking). Then a Custom Event trigger fires your GA4 or Google Ads tag.

Can GTM track YouTube videos?

Yes, YouTube is the rare embed GTM handles natively. Enable the built-in YouTube Video trigger and GTM listens for play, pause, progress and complete with no custom code, as long as the embed allows the JS API (enablejsapi=1). Fire GA4 video_start and video_complete events off it.

How do I track HubSpot form submissions in GTM?

HubSpot forms broadcast a callback message. Add a listener for the hsFormCallback message with eventName onFormSubmitted, push an event like hubspot_form_submit (with the form id) to the dataLayer, and fire a GA4 or conversion tag on a Custom Event trigger matching it.

Why can't GTM see clicks inside an embed?

Embeds load in a cross-origin iframe, and browser security prevents the parent page (and your GTM container) from reading another origin's DOM or clicks. That's why you track them by listening for the events the embed deliberately broadcasts, via postMessage or its JS SDK, rather than watching the iframe directly.

Related posts

About the author

Nathan Gage
Nathan Gage

Analytics & Tag Management Consultant

Nathan Gage got his start in marketing through Google Tag Manager. Seeing how tracking customer behavior could turn raw clicks into insight you can actually act on is what pulled him into the field. Since then he has worked both full time and as a consultant with 15 marketing agencies, supporting brands that spend anywhere from a thousand dollars a month to over a million. Along the way he built a multi-touch attribution app, and he created The Happy Tagger so anyone can practice GTM, GA4 and server-side tracking on a real container instead of a production site.