8. Advanced & Preferred: iFrame Purchase Tracking via postMessage
Tracking conversions and user activity accurately within an iFrame (like the Showpass embedded purchase widget) is a significant challenge due to browser privacy measures that increasingly block third-party cookies and tracking mechanisms.
To overcome this, Showpass advocates for a more robust method: iFrame tracking using the postMessage API. This technique allows secure communication between the Showpass iFrame (child) and your website (parent page), enabling the iFrame to send event data directly to your GTM container on the parent page.
Why Use postMessage for iFrame Tracking?
- Accuracy: Bypasses many issues related to third-party cookie restrictions, leading to more reliable data
- Privacy-Focused: Relies on direct communication rather than cross-domain cookie sharing for event data
- Recommended: Considered a best practice for iFrame tracking in modern web analytics
Further Reading
For more context on iFrame tracking challenges and solutions:
- Jellyfish Training - How to Track iFrames with Google Tag Manager: https://www.jellyfish.com/en-gb/training/blog/how-track-iframes-google-tag-manager
- MeasureSchool - iFrame Tracking with Google Tag Manager: https://measureschool.com/iframe-tracking/
Overview of the postMessage Setup with Showpass
This setup involves two Google Tag Manager containers:
Child GTM Container (for the Showpass iFrame):
- Create a new empty GTM Container ID
- This container is specifically for the Showpass widget environment
- Its role is to capture ecommerce events within the iFrame and
postMessagethem to the parent window (your website) - Add this to your Organizer Info > Analytics section in the Showpass Dashboard
Parent GTM Container (on your website):
- This is your existing GTM container that manages tracking for your primary website
- Its role is to listen for messages from the Showpass iFrame and then push that data into its own
dataLayerto trigger your standard ecommerce tags (e.g., GA4, marketing pixels)
A. Child GTM Container Setup (Showpass iFrame GTM)
Step A1: Create the "Post Message to Parent" Tag
This tag will send data from the iFrame's Data Layer to your parent website.
Set Up the nonce Variable in GTM
This variable will read a dynamic nonce value that Showpass makes available on the page.
- In your GTM container, navigate to Variables
- Under "User-Defined Variables," click New
- Name your variable:
nonce(lowercase is conventional) - Variable Configuration:
- Click Choose a variable type to begin setup...
- Select DOM Element
- Selection Method: Choose CSS Selector
- Element Selector: Enter
meta[name='csp-nonce']Note: This is a CSS selector that targets the meta tag Showpass uses to provide the nonce value.
- Attribute Name: Enter
contentNote: This is the content attribute on the meta tag that will hold the nonce string.
- Click Save
Set Up the postMessage tag
- In the Child GTM container, go to Tags and click New
- Name the tag:
Custom HTML - Post Message Ecommerce Data to Parent - Tag Configuration:
- Choose tag type: Custom HTML
- Paste the following script into the HTML field:
<script nonce="{{nonce}}">
// Assuming you've set up a 'nonce' variable as per Section 5
(function () {
try {
// Check if running in an iFrame and if parent and postMessage are accessible
if (typeof parent != "undefined" && parent != window) {
if (typeof parent.postMessage != "undefined") {
// !!! IMPORTANT: Update dataLayer_GTM_CHILD_ID below !!!
// Replace 'GTM_CHILD_ID' with the actual ID of THIS Child GTM container
var message = window.dataLayer_GTM_CHILD_ID;
// Ensure message is an array and has content before sending
if (Array.isArray(message) && message.length > 0) {
// Deep clone the message to avoid issues with object references
var clonedMessage = JSON.parse(JSON.stringify(message));
parent.postMessage(clonedMessage, "*"); // Send to any parent origin for flexibility
}
}
}
} catch (err) {
// console.error("Showpass Child GTM postMessage Error: ", err);
}
})();
</script>
- Crucial:
- Ensure you have enabled the Support document.write checkbox, under the HTML field
- Replace
GTM_CHILD_IDin the script with your actual Child GTM Container ID (e.g.,dataLayer_GTM_XXXXXX). Note the underscore, not dash
- Triggering:
- Click Choose a trigger to make this tag fire...
- Select Custom Event
- Event name: Use regex matching to fire on all Showpass ecommerce events:
view_item|add_to_cart|remove_from_cart|begin_checkout|purchase|ecommerce_clear - Check Use regex matching
- Click Save
Step A2: Publish the Child GTM Container
- In the Child GTM container, click Submit
- Provide a version name (e.g., "Initial postMessage Setup")
- Click Publish
Step A3: Add Child GTM Container ID to Showpass
- Log in to your Showpass Dashboard
- Navigate to Organizer Info > Analytics
- Add your Child GTM Container ID (e.g.,
GTM-XXXXXXX) - Save changes
Showpass will now load this Child GTM container within the iFrame, allowing it to capture events and send them to the parent page.
B. Parent GTM Container Setup (Your Website)
On your parent website's GTM container, you need to set up a listener that receives the messages from the Showpass iFrame (child GTM) and pushes them to dataLayer of your Parent GTM.
Step B1: Create the "postMessage Listener" Custom HTML Tag
This tag listens for messages from the Showpass iFrame and processes them.
- In your Parent GTM container, go to Tags and click New
- Name the tag:
Custom HTML - Listen for Showpass iFrame postMessage - Tag Configuration:
- Choose tag type: Custom HTML
- Paste the following script:
<script nonce="{{nonce}}">
// Assuming you've set up a 'nonce' variable as per Section 5
(function () {
try {
var receiveMessage = function (event) {
try {
// Optional: Add origin check for security if Showpass iFrame origin is fixed and known
// if (event.origin !== "https://widgets.showpass.com") return;
if (
event &&
typeof event.data != "undefined" &&
Array.isArray(event.data)
) {
for (var i = 0; i < event.data.length; i++) {
if (event.data[i] && typeof event.data[i].event != "undefined") {
// Push specific, expected ecommerce events to the parent dataLayer
// You can expand this list based on what you want to track from the iFrame
if (
event.data[i].event == "view_item" ||
event.data[i].event == "add_to_cart" ||
event.data[i].event == "remove_from_cart" ||
event.data[i].event == "begin_checkout" ||
event.data[i].event == "purchase" ||
event.data[i].event == "ecommerce_clear"
) {
// Create a new object to avoid potential reference issues
var eventToPush = JSON.parse(JSON.stringify(event.data[i]));
dataLayer.push(eventToPush);
}
}
}
}
} catch (err) {
// console.error("Parent GTM postMessage Listener Error (inner): ", err);
}
};
if (typeof window.addEventListener !== "undefined") {
window.addEventListener("message", receiveMessage, false);
} else if (typeof window.attachEvent !== "undefined") {
// For older IE
window.attachEvent("onmessage", receiveMessage);
}
} catch (err) {
// console.error("Parent GTM postMessage Listener Error (outer): ", err);
}
})();
</script>
Security Note: In production, you should verify
event.originto ensure messages are only accepted from trusted sources (e.g.,https://showpass.comor your own domain).
- Triggering:
- Click Choose a trigger to make this tag fire...
- Select Window loded trigger
- This ensures the listener is set up as soon as the page loads
- Click Save
Step B2: Create a trigger for ecommerce events
- In the current GTM container, go to Triggers and click New
- Name your trigger: A descriptive name like
Custom - Showpass Ecommerce EventsorEcommerce Triggers | All Events - Trigger Configuration:
- Click Choose a trigger type to begin setup...
- Select Custom Event
- Event name: Enter the following, using a pipe
|to separate event names:view_item|add_to_cart|remove_from_cart|begin_checkout|purchase|ecommerce_clearNote:
ecommerce_clearis a custom event that clears the ecommerce cache in the data layer - Check the box for Use regex matching. This allows the trigger to fire on any of the listed events
- This trigger fires on: Select All Custom Events
- Click Save
- Update your existing tag to use this trigger. Your
Custom HTML - Listen for Showpass iFrame postMessageshould now trigger bothWindow LoadedandCustom - Custom - Showpass Ecommerce Events
For tracking specific single events like add_to_cart - please see Tracking Custom Conversions
Step B3: Verify Your Parent GTM Ecommerce Tags
Ensure that your parent GTM ecommerce tags (e.g., GA4 Ecommerce Event tag, marketing pixel tags) are configured to fire on the events pushed to the dataLayer by the postMessage listener.
- Your existing triggers for events like
purchase,add_to_cart, etc., should automatically catch these events once they're pushed to the parent'sdataLayer - No additional changes are typically needed if your parent GTM setup is already configured to listen for these standard ecommerce events
Step B4: Publish Your Parent GTM Container
- In your parent GTM container, click Submit
- Provide a version name (e.g., "Added iFrame postMessage Listener")
- Click Publish
Testing the postMessage Setup
Test your setup using https://tagassistant.google.com/
- Enable GTM Preview Mode on both your Parent and Child GTM containers (if possible)
- Navigate to a page on your website that contains the Showpass embedded widget
- Perform ecommerce actions within the widget (e.g., add to cart, purchase)
- In the Parent GTM Tag Assistant:
- Look for your ecommerce events (e.g.,
add_to_cart,purchase) appearing in the event timeline - Verify that your GA4 Ecommerce Event tag and other marketing tags fire as expected
- Look for your ecommerce events (e.g.,
- Check browser console:
- Look for any errors related to postMessage
- You can add
console.log()statements in your postMessage listener script to debug
Summary
- Child GTM Container: Captures ecommerce events within the Showpass iFrame and sends them via
postMessageto the parent page - Parent GTM Container: Listens for
postMessageevents and pushes them to its owndataLayer, triggering standard ecommerce tags - Benefits: More accurate tracking, bypasses third-party cookie restrictions, privacy-focused approach
- Always test thoroughly and verify
event.originin production for security