UNPKG

c15t

Version:

Headless JavaScript consent management platform for cookie banners, privacy preferences, consent storage, and script gating.

98 lines (72 loc) 3.27 kB
--- title: Iframe Blocking description: Block embedded content (YouTube, social widgets, maps) until users grant consent for the appropriate category. group: frameworks --- Embedded iframes from third parties (YouTube, Google Maps, social media widgets) can set cookies and track users without their consent. c15t provides two approaches to gate iframes behind consent: 1. **`<Frame>` component** - A React component that conditionally renders children based on consent 2. **HTML `data-category` attribute** - For raw `<iframe>` elements outside of React ## HTML Attribute Approach For vanilla JavaScript, use `data-category` and `data-src` attributes on `<iframe>` elements: ```html <iframe data-src="https://www.youtube.com/embed/dQw4w9WgXcQ" data-category="marketing" width="560" height="315" ></iframe> ``` When consent for the specified category is granted, c15t automatically swaps `data-src` to `src`, loading the iframe. When consent is revoked, `src` is moved back to `data-src`. ### Dynamic Iframes c15t uses a `MutationObserver` to watch for dynamically added iframes. Any iframe with `data-category` added to the DOM after initialization is automatically processed. ## Initializing the Iframe Blocker The iframe blocker for HTML attributes needs to be initialized after the runtime is created: ```ts import { getOrCreateConsentRuntime } from 'c15t'; const { consentStore } = getOrCreateConsentRuntime({ mode: 'hosted', backendURL: 'https://your-instance.c15t.dev', }); // Initialize the iframe blocker consentStore.getState().initializeIframeBlocker(); ``` The blocker will scan the DOM for all `<iframe>` elements with `data-category` and manage their `src`/`data-src` based on consent state. It also sets up a `MutationObserver` to handle iframes added later. ## Custom Placeholder Build a consent placeholder with vanilla DOM that's shown when consent is not granted: ```ts function createIframePlaceholder(category: string, iframeSrc: string) { const container = document.createElement('div'); container.className = 'iframe-placeholder'; container.innerHTML = ` <p>Enable ${category} cookies to view this content.</p> <button class="consent-button">Grant Consent</button> `; const button = container.querySelector('.consent-button'); button?.addEventListener('click', () => { consentStore.getState().setConsent(category, true); }); // Replace placeholder when consent is granted consentStore.subscribe((state) => { if (state.has(category)) { const iframe = document.createElement('iframe'); iframe.src = iframeSrc; iframe.width = '560'; iframe.height = '315'; container.replaceWith(iframe); } }); return container; } ``` ## Cleanup Destroy the iframe blocker when it's no longer needed (e.g., on page teardown in a SPA): ```ts consentStore.getState().destroyIframeBlocker(); ``` ## API Reference |Property|Value| |:--|:--| |Type Name|\`FrameProps\`| |Source Path|\`./packages/react/src/components/frame/types.ts\`| \*ExtractedTypeTable: Could not extract "FrameProps" from "./packages/react/src/components/frame/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*