# Consent inside iframes: the postMessage consent relay pattern

Source: https://cookiebastion.com/blog/2026-10-07-consent-iframe-postmessage-relay.html

[Home](../index.md) / [Blog](index.md)Consent inside iframes: the postMessage consent relay patternConsent inside iframes: the postMessage consent relay pattern


Published 2026-10-07

Your consent setup works on your pages. Then you embed a third-party widget in an iframe: a booking form, a payment flow, a support chat. The iframe loads its own scripts, sets its own cookies, and fires its own trackers, all inside a browsing context your banner's blocking rules cannot reach. The visitor consented or refused on your page. The iframe never got the memo.

This is the iframe consent gap, and it is structural. Blocking scripts on your page does not block scripts inside a cross-origin iframe. The browser's same-origin policy means your consent code cannot reach in and flip the iframe's tracking off. You need a relay: your page tells the iframe what the visitor chose, and the iframe's own code honors it.

## Why iframes ignore your banner

Consent blocking usually works by intercepting script loads or by gating a consent state variable that your tags check before firing. Both mechanisms operate in your page's context. A cross-origin iframe is a separate context with its own scripts, its own storage, and its own network requests. Your page's blocking rules stop at the frame boundary.

Worse, many embedded widgets initialize tracking the moment the iframe loads, before any consent handshake could complete. The booking widget fires its analytics on load. The chat widget sets its identification cookie on render. By the time your page could tell the iframe anything, the tracking already happened.

## The postMessage relay pattern

The standard solution is a consent relay over postMessage. Your page holds the canonical consent state. When the state is set or changes, your page posts a message to each embedded iframe carrying the consent decision. The iframe's code listens for that message and applies it to its own tracking: enabling or disabling its scripts, gating its cookie writes, honoring the refusal.

The relay has to handle timing in both directions. Iframes often load before the visitor interacts with the banner, so the iframe must request the current state on its own load, not just wait for updates. And the page must re-broadcast whenever consent changes, because a visitor can update their choice after the iframe already initialized. The handshake is: iframe asks on load, page answers immediately, page re-sends on every change.

Origin validation is non-negotiable on both ends. The page should only send consent state to iframes from expected origins, and the iframe should only accept state messages from the parent origin it trusts. Consent state is sensitive; an open relay that accepts messages from any origin is a spoofing vector.

## What to do when the widget vendor does not support it

Here is the uncomfortable part: the relay only works if the iframe's code participates. Many widget vendors do not expose any consent API at all. Their embed code loads, tracks, and offers no switch. For those vendors, postMessage has nothing to talk to.

In that case your options narrow. You can delay loading the iframe until the visitor consents, which is the honest approach: no consent, no embed. You can replace the iframe with a click-to-load facade, a static preview that only loads the real widget after an explicit click, which doubles as consent for that specific embed. Or you can switch vendors to one that exposes a consent interface. What you cannot do is claim the widget is covered by your banner when it is not.

## Testing the relay

Test with the network tab scoped to the iframe's requests. Reject all in the banner, then check whether the iframe's trackers fire. The most common failure: the iframe loads and tracks before the relay message arrives, a race your tests need to catch by throttling the network, not just on a fast connection.

Also test the change path: load with consent accepted, then open the banner and switch to reject. The iframe should stop its tracking without a page reload. If it only reads consent once at load, late changes do nothing, and the visitor's updated choice is fiction inside the frame.

## The bottom line

Iframes are separate consent jurisdictions, and your banner's authority stops at the frame boundary. Build the postMessage relay, validate origins on both ends, handle the load-before-consent race, and for vendors that offer no consent interface, gate the embed behind the choice itself. Consent that does not cross into the iframe is not complete. It is just well-decorated.

## Common questions

**Can I block iframe tracking from the parent page without vendor cooperation?**

Not reliably. Sandboxing the iframe can restrict some capabilities, but it breaks most widgets and does not stop all tracking. Real consent inside the frame needs the framed code to participate.

**Does a same-origin iframe have this problem?**

Mostly no. Same-origin iframes share your page's context, so your blocking rules and consent state apply directly. The relay pattern is for cross-origin embeds, which is what third-party widgets are.

**Is click-to-load enough for compliance?**

It is one of the strongest patterns available: no tracking code loads until the visitor takes an affirmative action on that specific embed. It sidesteps the relay entirely by making loading itself the consent event.

## Get a free consent audit of your website

[Free consent audit](mailto:hello@cookiebastion.com?subject=Free%20consent%20audit%20-%20cookiebastion.com)

## Frequently asked questions

### What records should a consent banner itself keep?

Keep the timestamp, the notice and banner version shown, the categories offered, and the exact choice made, tied to an anonymous identifier. Those records are your proof if a choice is ever questioned.

### Should reject be as easy to find as accept?

Yes. Equal prominence is the standard regulators apply, because a hidden reject path makes acceptance the product of design pressure rather than choice. Test both paths with real users on mobile screens.

### What happens when a consent tool updates its categories?

When categories change, choices recorded against the old set may not map cleanly. Material changes should trigger a fresh ask for affected visitors rather than a silent remapping of their earlier decision.
