embedConsent
Holds a third-party embed's place until the visitor has allowed it — and skips the asking where they already have.
Every box below is a facade: a locally hosted poster, a notice saying who would receive what, a button that loads it, and a link to the content at the provider for anybody who would rather go there. Nothing is requested from Google, Vimeo or OpenStreetMap until one of the two lanes says it may be.
Your consent platform, played by two buttons
These are not part of the component and not a
cookie banner. They write and clear
<html data-consent>, which is all the shipped
gate lane reads — a real platform writes the same attribute from
its own callback, in about five lines. Everything else on this
page reacts to it without knowing it exists.
It does store, though — in localStorage, which is
what makes example 6 honest: a component that stores nothing is
only interesting if something else does. Reload the page after
allowing something and it is still allowed, with no notice ever
drawn for it.
Consent for YouTube, Google Maps and OpenStreetMap:
1 — YouTube, with a poster
The click lane in full. The poster is served from this
project — a provider's thumbnail endpoint would be the very
request being deferred. Press the button and the player is
built with autoplay — which is what its label
promises — and granting consent above builds the same player
without it.
2 — Google Maps, no poster
Without a poster the notice sits on the component's own
surface, which for a map is the honest rendering. This one asks
the gate for googleMaps and
marketing: the first is what a per-service
platform answers, the second what a category-only platform can.
Either one is enough.
3 — OpenStreetMap
The same wiring, one attribute different. Whether this one needs consent at all is a project's call — the IP still travels — but there is no advertising business at the other end of it, and that is the cheapest answer to the whole question there is.
4 — No notice, no button
The notice element is here but empty, so the script leaves the button hidden and reports why. This is the one place the component overrules the author: a button that loads third-party content without saying who receives what is not informed consent. The link still works, and granting consent above still fills the box — a platform collected its own consent with its own information.
5 — One press, a whole group
A page with six videos on it costs a visitor six presses.
data-embedconsent-group lets one press fill every
other box naming the same service token — for this page view,
storing nothing, exactly as a single press stores nothing. Press
either button below and both boxes fill; only the one
you pressed starts playing, because nobody asked for the other
one. Example 1 above is YouTube as well and stays
put: it carries no group attribute, and the default is
and remains one press, one box.
Two things to listen for. The buttons are empty in the markup, so the script writes the label — and it says the press reaches further, because a control that describes itself wrongly is the one thing this component will not ship. And the box you press announces once, on behalf of the group, that another embed was loaded too; the box that filled without being asked stays silent, so six boxes never produce six announcements.
6 — Deciding once, for good
Everything above covers one page view. This box offers the other
thing as well: load it and always allow YouTube. The
press does exactly what the plain button does — the player is
there, playing, because that is what the label promised — and
then hands the token youtube to the
platform through services.consent.grant(). The
platform stores it, writes data-consent, and the
gate's subscription does the rest: watch every other YouTube box
on this page fill without being touched.
Then reload. No notice is drawn for any YouTube
box, not even for a moment — the fake platform in
<head> put the attribute on
<html> before the first paint. And the small
control in the corner of the box is the reason this lane is
allowed to exist at all: withdrawing has to be as easy as
consenting, so the component refuses to reveal the grant button
unless the way back is shipped with it.
Four more things it refuses, all of them in the console rather
than on screen: one of the two buttons without the other, a gate
with no grant/revoke callbacks, a box
with no data-embedconsent-service (a category is
more than this notice explained), and a box whose plain load
button is unavailable — a lasting decision may never be the only
way to see a video.