The short version
- The rule is about storing or reading anything on the visitor's device. localStorage counts. Saying “no cookies” does not exempt you.
- There is a narrow exemption for storage strictly necessary to provide a service the user explicitly requested. “Remember that this visitor dismissed the popup” usually sits inside it; analytics does not.
- A third-party iframe can set cookies from ITS domain the moment it loads, before the visitor touches anything. That is the real risk in a YouTube or map embed.
- A widget that makes no network request and stores nothing has nothing to declare.
- Loading a web font from a third-party CDN transmits the visitor's IP address to that party, with no cookie involved at all.
- Whatever you conclude, your privacy policy has to name what is actually loaded. That is the part most sites get wrong and the part that is easiest to fix.
This is not legal advice, and the answer for your site depends on where you and your visitors are. What follows is the technical picture underneath the legal question, because most of the confusion comes from getting that part wrong rather than from the law itself.
The single most common mistake is treating “cookie” as the boundary. In the European rules that most of the world's consent banners are built for, the trigger is storing information on, or reading information from, a user's device — the mechanism is not named. `localStorage`, `sessionStorage`, IndexedDB and a cookie are all the same thing for this purpose. “We use no cookies, we use local storage” is not the exemption it is often presented as.
The boundary is storage, not cookies
The ePrivacy rules that consent banners exist to satisfy talk about the storing of information, or the gaining of access to information already stored, in the terminal equipment of a subscriber or user. Nothing in that sentence is specific to cookies. A key in `localStorage` is information stored on the device, and reading it back on the next page view is gaining access to it.
This matters because “we don't use cookies” has become a standard vendor claim, and it is usually true and usually irrelevant. A widget that writes `dismissed=1` to `localStorage` is doing the same thing a cookie would, minus the network transmission.
The transmission difference is not nothing, though. A cookie is sent to the server on every matching request; `localStorage` never leaves the browser unless the page explicitly sends it. So local storage is genuinely more private in practice — it is just not outside the rule.
| Mechanism | Sent to a server automatically | Survives a browser restart | In scope for consent rules |
|---|---|---|---|
| Cookie | Yes, on every matching request | If it has an expiry | Yes |
| localStorage | No | Yes, until cleared | Yes |
| sessionStorage | No | No, cleared with the tab | Yes |
| IndexedDB | No | Yes | Yes |
| In-memory variable | No | No, gone on reload | No |
The strictly-necessary exemption, and what it actually covers
There is an exemption for storage that is strictly necessary in order to provide a service explicitly requested by the user. It is narrower than most sites assume and wider than the strictest reading suggests.
The clearest case inside it is remembering a choice the visitor just made. If someone closes a popup and you store a flag so it does not reappear on the next page, that storage exists solely to honour what they did. Refusing to store it — and therefore showing the popup again — would be worse for them, which is a good test of whether something is genuinely necessary.
The clearest cases outside it are analytics, advertising, personalisation and anything that builds a profile across sites. Several regulators have said explicitly that first-party analytics is not exempt, however anonymous the vendor claims it is.
The murky middle is where honest people disagree: A/B testing, session replay, and “remember this so we can show a different offer next time”. If the storage serves your interest rather than the visitor's stated request, assume it needs consent.
- Inside: a dismissal flag, a shopping basket, a login session, a language choice the visitor made, load balancing.
- Outside: analytics of any kind, advertising identifiers, cross-site tracking, personalisation the visitor did not ask for.
- The test that works: would the visitor be worse off if you did NOT store it? If yes, it is probably necessary. If you would be worse off, it is probably not.
Third-party iframes are the real problem
The widget class most likely to create a genuine consent obligation is the one people worry about least: an embedded video, a map, or a social post. These load a document from the vendor's own domain, and that document can set its own cookies the instant it appears — before your visitor has clicked anything, and regardless of what your banner says.
This is why “privacy-enhanced” embed modes exist. YouTube's `youtube-nocookie.com` domain defers its identifier cookies until playback begins, which moves the trigger from page load to a deliberate user action. Several map and social embeds have similar modes, and they are worth using even where you have consent, because they reduce what you have to explain.
The pattern that solves it properly is click-to-load: render a static thumbnail and only insert the iframe when the visitor asks for the content. That is better on every axis — no third-party request on load, no cookie before consent, and a much faster page.
Fonts, images and the request nobody thinks about
Storage is not the only thing that transmits data. Every request a widget makes sends the visitor's IP address, user agent and referring page to whoever is on the other end — no cookie required, no storage involved.
This is why loading a web font from a third-party CDN has repeatedly been ruled a data transfer in its own right, most prominently in a German court decision on Google Fonts. Whether that reasoning applies to you is a legal question, but the technical fact is not in dispute: a font request tells that provider who is reading your page.
The same applies to avatars, logos and images a widget pulls from a vendor's CDN. A widget that renders entirely from configuration you supplied, using fonts already on the visitor's machine, makes no such transfer.
- Self-host your fonts, or inherit the ones the page already loads. A widget that ships its own typeface is adding an origin and a data transfer for a cosmetic gain.
- Check where a widget's images come from. “Your own images” and “our CDN” are different answers.
- A widget that makes zero requests after its own script transmits nothing beyond that one download.
Auditing an embed in five minutes
You do not need a compliance tool for this. Open the vendor's demo page in a private window with your developer tools open, and look at three panels.
- Application → Storage: expand Cookies, Local Storage and Session Storage. Anything there arrived without consent. Note the domain each key belongs to — a key on the vendor's domain is theirs, not yours.
- Network: filter by domain. Every distinct origin is a party receiving your visitor's IP address. Look specifically for font, image and analytics hosts you did not expect.
- Network again, this time after interacting: click the widget and watch what fires. Some vendors defer their tracking until first use, which changes what you have to declare and when.
- Then repeat with the vendor's domain blocked, to see what your page looks like when they are down. That answers a different question, but you are already there.
What your privacy policy has to say either way
This is the part almost every site gets wrong, and it is the easiest to fix. Whatever you conclude about consent, your privacy policy has to describe what is actually loaded on your pages: which third parties, what they receive, and what they store.
The failure mode is not usually a missing banner — it is a policy written before the widget was added and never updated. A page saying “we set no cookies” above a chat widget that sets three is a straightforwardly false statement about your own site, and unlike a debatable consent question it is not arguable.
So treat the policy as part of the change. When you add an embed, add the vendor to the list in the same week you paste the snippet, not in the next annual review.
How Zyff's own widgets behave
Zyff's widgets set no cookies. What some of them do store is a single flag in the visitor's own `localStorage` — that this person closed the popup, dismissed the chat menu, or confirmed their age — under a key namespaced to that widget so two widgets on one page cannot collide. That is the dismissal case described above, and it exists purely so the widget honours what the visitor already did.
They load no web fonts. The default typeface setting inherits whatever the host page uses, and every other option is a stack of fonts already present on the visitor's machine, so no font request is ever made to any origin.
A snippet with its settings inlined makes no network request at all beyond the script file itself — the configuration travels inside the snippet. A saved widget fetches its current configuration from Zyff so that editing it updates every site it is embedded on; that is one request to one origin, and it is the trade you accept in exchange for not having to re-paste the code.
None of that decides your obligations, which depend on where you are and what else is on your page. It does mean the audit above is short.
Try it on Chat Widget
Free, no signup, no watermark. Runs on Zyff’s servers, so you get the same result on a phone as on a desktop.
At a glance
| In scope for consent rules | Cookies, localStorage, sessionStorage, IndexedDB |
|---|---|
| Out of scope | Values held only in memory for the life of the page |
| Usually exempt | Storage honouring a choice the visitor just made |
| Never exempt | Analytics, advertising, cross-site identifiers |
| Transmits data with no storage | Any request to a third-party origin, including fonts |
| Zyff widgets | No cookies; one namespaced localStorage flag where a widget can be dismissed |
Frequently asked questions
Do website widgets need cookie consent?
It depends on what they store and why, not on whether the mechanism is called a cookie. A widget that stores nothing and contacts nobody needs no consent. One that sets an analytics or advertising identifier does. One that stores only a flag remembering the visitor closed it usually falls inside the strictly-necessary exemption — but this is a question for someone who knows your jurisdiction.
Does localStorage need consent?
It is in scope for the same rules as cookies. The European provision is about storing information on, or reading it from, a user's device, and it does not name a mechanism. “We use local storage, not cookies” is a true statement that does not, by itself, exempt anything.
Are YouTube embeds a problem?
They are the most common real one. A standard YouTube embed loads a document from Google's domain that can set cookies on page load, before the visitor clicks play. The youtube-nocookie.com domain defers that until playback starts, and a click-to-load thumbnail avoids it entirely until the visitor asks for the video.
What about Google Fonts?
No cookie is involved, but the request itself transmits the visitor's IP address to Google, and a German court has treated that as a data transfer in its own right. Self-hosting the font files, or using fonts already installed on the device, removes the question.
Is a chat widget strictly necessary?
The chat function is a service the visitor explicitly requests when they click it, and storage that remembers they closed it serves them rather than you. Storage that identifies them across sessions or sites for marketing does not. The same widget can be on both sides of the line depending on what it stores.
How do I find out what a widget stores?
Open the vendor's demo page in a private window with developer tools open, and look at Application → Storage for cookies and local storage, then the Network panel for every origin contacted. Anything present before you interact with the page arrived without consent.
Does a consent banner block the widget by itself?
No, and this is the most expensive misunderstanding in this area. A banner that records a choice but does not gate script execution changes nothing about what loads — it just adds a record. Real blocking means the third-party script does not run until consent is given, which requires the banner and the embed to be wired together.
Do I need to update my privacy policy?
Yes, and this is the part most often missed. Whatever you decide about consent, the policy has to name what is actually loaded on your pages and what each party receives. A policy that says “no cookies” above a widget that sets three is false in a way that is not arguable.