Skip to main content

JavaScript Modules

Iframe blocker

Gate an embed

Put the embed's URL in data-src instead of src, and name its category in data-category:

index.html
<iframe
	data-src="https://www.youtube-nocookie.com/embed/czTksCF6X8Y?playsinline=1"
	data-category="measurement"
	title="YouTube video"
	allow="encrypted-media; picture-in-picture"
	allowfullscreen
></iframe>

The iframe blocker gives the iframe its src once the category is allowed, and takes it away again when the visitor withdraws it. An iframe without src loads nothing, so the vendor gets no request before consent. @c15t/browser and createConsentRuntime run the blocker by default.

Attributes

AttributeWhat it does
data-srcThe embed's URL. Only http: and https: URLs load. Relative URLs resolve against the page.
data-categoryOne category name. An unknown name logs a warning and keeps the iframe blocked.
data-vendorOptional vendor slug. The iframe also stays blocked while the visitor has turned that vendor off.
data-c15t-pausedSet by c15t when it removed a src the iframe already had.

Iframes without data-category or data-vendor are left alone. An iframe written with src and data-category starts loading before the blocker runs, so always use data-src.

Iframes your code adds

The blocker watches the whole document for new iframes and for changes to data-category and data-vendor. An iframe your app renders after load is gated as soon as it is inserted, before the browser fetches it, as long as it is inserted with data-src and no src. Watching the document root keeps the blocker working when a client router such as Turbo replaces <body>, and lets it start from a script in <head> before <body> exists.

To render the embed yourself instead, skip the attributes and create the iframe when snapshot.effectivePermissions.measurement becomes true. The headless example does this for its YouTube video.

Show a placeholder

c15t draws nothing in place of a blocked iframe. Show your own message beside it and hide it once the iframe has a src:

iframe[data-category]:not([src]) { display: none; }
iframe[src] + .placeholder { display: none; }

Give the placeholder a button that calls consent.openDialog(), so the visitor can allow the category.

Configure it

iframeBlocker valueEffect
omitted or {}Gate every iframe with data-category or data-vendor.
{ disableAutomaticBlocking: true }Do not scan or watch the page. c15t checks iframes only when you call processIframes(). See check iframes on demand.
falseNo blocker. data-src iframes never load.

The categories of gated iframes are added to the categories the preference dialog offers.

Check iframes on demand

With iframeBlocker: { disableAutomaticBlocking: true }, the blocker does nothing until you call processIframes(). Each call pauses gated iframes, those with data-category or data-vendor, that consent does not allow, and restores the ones it does. Call it after you add iframes and after consent changes:

consent.on('consent', () => consent.processIframes());

consent.processIframes() is on the @c15t/browser client, and runtime.processIframes() on a runtime from createConsentRuntime. The call does nothing before start(), after dispose(), or when iframeBlocker is false. With automatic blocking on, the blocker does this by itself.

Attach it to your own kernel

A kernel from createConsentKernel has no iframe blocker. Create one for it:

src/iframe-blocker.ts
import type { ConsentKernel } from 'c15t';
import { createIframeBlocker } from 'c15t/modules/iframe-blocker';

// Watches the page for <iframe data-src data-category> and sets `src` while
// the category is allowed.
export const gateIframes = function gateIframes(kernel: ConsentKernel) {
	return createIframeBlocker({ kernel });
};

createIframeBlocker returns { dispose, processAllIframes }. processAllIframes() scans the page again and applies the current consent. dispose() stops watching and leaves the iframes as they are.

Check it works

  1. Before a choice, the iframe has no src and the Network tab shows no request to the embed's host.
  2. Allow the category. The iframe gets its src and loads.
  3. Add an iframe with data-src from the console after the page loaded. It loads only while its category is allowed.