
Every YouTube video, Google Map and Instagram post on your site contacts its provider the moment the page opens — before the visitor has agreed to anything. Calucon Third-Party Embed Gate holds those embeds behind a click-to-load placeholder. Until the visitor presses “Load”, nothing is requested from the provider and nothing is stored on their device — not by the provider, and not by this plugin. That is the two-click solution (Zwei-Klick-Lösung), done properly: no cookie banner, no consent platform, no account, no subscription. It works the moment it is activated.
See it on the live demo — all 36 providers on one page, 30 of them with live content, and zero third-party requests until you press a button — or read the details on the plugin page.
Why it matters
A plain request to www.youtube.com/embed/… — no playback, no scripts run — sets six cookies, four of them identifiers that live about six months (measured August 2026). Every visitor gets them on every page with a video, whether or not they ever press play. The same request to www.youtube-nocookie.com sets none, and that is where this plugin loads YouTube from after the click.
How it works
- You keep writing posts as before: paste a URL, WordPress makes the embed, and editors see the normal embed in the block editor.
- Visitors see a placeholder instead — rendered on the server, so it is there before any JavaScript runs: the provider’s name and icon, one sentence on what loading means, a real “Load” button, and a plain link to the content for anyone who prefers to open it there.
- On the click, that one embed loads — from the privacy-preserving address where the provider has one. Nothing else on the page changes, and nothing loads for embeds the visitor did not ask for.
What you get
- Works on activation, with no configuration, no account and no external service.
- Names 36 embed types — every one WordPress offers out of the box, from YouTube and Vimeo to Spotify, Google Maps, X, Instagram, TikTok and Calendly — with an icon, a notice, an optional privacy-policy link and a working no-JavaScript link. Anything it does not know is gated all the same: the plugin gates by host, not by a list, so a new tracker is never let through by accident.
- Finds the embeds your caching and optimisation plugins have already minified — attribute quotes stripped, newlines inside tags — which is where most implementations silently fail. Also lazy-loaded markup (
data-src), the loader scripts and stylesheets some embeds bring along, and content delivered over AJAX and the REST API (“load more”, infinite scroll). - Accessible and JavaScript-free by design: a named group, a real button, visible focus, sufficient contrast, focus kept after loading; zero axe-core violations in CI. Without JavaScript the link still works.
- Loads from privacy-preserving endpoints where they exist:
youtube-nocookie.com, Vimeo withdnt=1. Rebuilds every embed from an attribute safelist —sandboxpreserved,autoplaynever survives — and strips thepreconnectanddns-prefetchhints that would contact the provider early. - Looks like your site, without CSS: quick styles, colours that follow your theme’s palette, corners, borders, shadows, button styles and dark-mode colours, with a live preview and an automatic readability check — plus a poster image per embed from your own media library, never fetched from the provider, and per-embed button and notice text in the block editor.
- Speaks German: the plugin ships translated for all five German locales (Germany du and Sie, Austria, Switzerland), and the texts you type are registered for WPML and Polylang.
- Optional and off by default: remember the visitor’s choice in their browser (per embed, per provider or for all; for the session or a number of days) with a withdrawal block and shortcode — and a bridge to your consent platform, so a consent given there loads the embeds and a withdrawal there re-gates them.
- Never phones home. No telemetry, no update check against a private server, no remote font or script — no outbound request from your server or your visitors’ browsers, on any path, for any reason.
Works with
- Caching and optimisation plugins: W3 Total Cache, WP Super Cache, LiteSpeed Cache, Autoptimize, WP Fastest Cache, SiteGround Optimizer, WP Rocket. Gating happens on the server, so the cached page is the gated one; Status & tools names the files to exclude from “delay JavaScript” and where that plugin keeps its list.
- Consent platforms, through the optional bridge: WP Consent API, Complianz, Cookiebot, CookieYes, Borlabs Cookie 3, Real Cookie Banner. The bridge only reads the platform’s answer; with any other platform, or no answer, gating stands.
- Page builders: Elementor’s HTML and video widgets are gated out of the box. For a builder that renders outside WordPress’s content filters, “Gate the whole page output” under Detection reads the finished page instead.
- Multilingual sites: WPML, Polylang, TranslatePress, Weglot.
Every month those claims are re-tested on a real WordPress against the current versions of the plugins that are free to install; the ones that are not (WP Rocket, Borlabs Cookie, WPML, Weglot, Cookiebot’s banner) are tested against simulations of their documented behaviour.
What it is not
Calucon Third-Party Embed Gate is a technical measure, not a consent management platform. It prevents the embed providers’ requests until the visitor acts, and the click is consent for that one embed (or, with consent memory on, for the scope you configure). It does not produce consent records for accountability purposes, it does not audit your site for other trackers, and it makes no legal claim about your site. Your privacy policy still has to name the providers you embed from, and your legal bases remain yours. If you need a documented consent record, you need a consent management platform.
For developers
- Theme override: copy
templates/placeholder.phpto{your-theme}/calucon-embed-gate/placeholder.php. - CSS custom properties on
.cg-embed(--cg-bg,--cg-fg,--cg-accent, …) for restyling without specificity wars. - WP-CLI:
wp calucon-embed-gate scan(is every embed gated?--format=jsonfor CI and automation) andwp calucon-embed-gate providers. Both read-only. - Documented filters:
calucon_embed_gate_providers,calucon_embed_gate_provider_for_url,calucon_embed_gate_should_gate,calucon_embed_gate_is_own_host,calucon_embed_gate_own_hosts,calucon_embed_gate_placeholder_html,calucon_embed_gate_payload,calucon_embed_gate_note_text,calucon_embed_gate_action_text,calucon_embed_gate_fallback_url,calucon_embed_gate_www_equivalence,calucon_embed_gate_cmp_config,calucon_embed_gate_asset_version,calucon_embed_gate_the_content_priority,calucon_embed_gate_render_block_priority, plus thecalucon_embed_gate_before_render,calucon_embed_gate_embed_gatedandcalucon_embed_gate_flush_cachesactions. Each one’s signature, when it fires and what to return are documented indocs/customizing.md, which ships inside the plugin (wp-content/plugins/calucon-third-party-embed-gate/docs/customizing.md) and is readable on GitHub. Adding a provider is a ten-line filter infunctions.php. - Stable since 1.0: the markup contract (
cg-classes,data-cg-*attributes,--cg-*custom properties), the documented hooks, the template variables, the settings keys and the WP-CLI commands do not change across minor releases; provider descriptors and the tested-platform lists are data and may.docs/customizing.mdships inside the plugin and is written for developers and AI coding agents alike.
External services
This plugin makes no request to any external service, on any page, at any time. It contacts no API, loads no remote script, font, image or update check, and sends no telemetry. Its entire purpose is the opposite direction: it prevents your pages from contacting embed providers.
Third-party content enters the picture only after a visitor clicks the “Load” button on an embed placeholder. At that moment the visitor’s browser loads that one embed from its provider (for example YouTube, Vimeo or Google Maps) — exactly as it would have without this plugin, except that it now happens on the visitor’s request instead of automatically. Each placeholder names the provider and, when the optional link is turned on under Providers, links the provider’s privacy policy before the click. The provider hostnames in the plugin’s source code exist solely so it can recognise and gate that content. No data is sent anywhere by the plugin itself.
Screenshots

A gated YouTube embed as a visitor sees it: a server-rendered placeholder with a named panel, a real "Load" button and a working fallback link — nothing is requested from the provider until the click.

The Appearance settings: quick styles, colours that follow your theme's palette, sections for shape, button, poster image, withdraw button and dark mode, a live preview of the real panel and an automatic readability check.

The content scan on Status & tools: every embed found in your recent posts and pages, the address it would contact, whether it is gated, and one click to name an unknown host or let it through.

The Providers tab: providers grouped by what the embed is, with a filter box — per-provider on/off, privacy-preserving load variants, custom notice and button text, the privacy-policy link and your own providers.

The per-embed control in the block editor: gate this embed always, never or per the site default, set a poster image from your own media library, and give it its own button and notice text.

The Content-Security-Policy helper: a check of your own site for a policy, the exact lines to add for the providers you have enabled, and which provider needs which host.