Do Chat Widgets Need Cookie Consent? What GDPR and ePrivacy Require
We measured what 13 chat widgets store before anyone clicks and mapped it to the ePrivacy consent rule, with a code pattern to load a widget after consent.

Short answer
A chat widget needs consent in the EU and UK for anything it stores on or reads from a visitor's device, localStorage included, unless an exemption applies, mainly that it is strictly necessary for a service the visitor requested. On 19 October 2026 we loaded 13 widgets on a blank page: 7 of the 10 that ran stored data before anyone clicked. Storage starting when the visitor opens the chat is easier to defend. This is not legal advice.
Does a live chat widget need cookie consent? The question can be settled with two facts you can check yourself: what the widget stores on, or reads from, the visitor's device, and whether that happens before the visitor asks for the chat or after.
The post is for site owners, marketers and developers with visitors in the EU, the EEA or the UK. It covers the rule in Article 5(3) of the ePrivacy Directive, a measured table of what 13 widgets store on a blank page, a decision table for strictly necessary versus consent, and a code pattern for loading any widget after consent. Legal texts and measurements are from 19 October 2026. This is general information, not legal advice: your lawyer or data protection officer makes the call for your site.
PepoChat is our product. It was measured exactly like the other widgets, and its section lists everything it stores, including the details your assessment should weigh.
Do chat widgets need cookie consent?
A chat widget needs consent unless everything it stores or reads on the visitor's device is strictly necessary to provide a service the visitor explicitly asked for. Article 5(3) of the ePrivacy Directive, as amended in 2009, allows storing information on a user's device, or gaining access to information already stored there, only with consent given after clear and comprehensive information. It names two exemptions: storage for the sole purpose of transmitting a communication, and storage strictly necessary for a provider to deliver a service "explicitly requested by the subscriber or user".
The strictly necessary exemption is that second carve-out: storage without which the service the user asked for could not work. For a chat widget the service is the chat, so what matters is what the widget does before a visitor asks for it and after.
Article 5(3) is not only a cookie rule. The European Data Protection Board's Guidelines 2/2023 on its technical scope, adopted in final form on 7 October 2024, say it covers similar technologies as well as cookies, that the protected information does not have to be personal data, and that a script instructing the browser to send information back counts as gaining access. The guidelines leave the exemptions to national regulators, case by case.
Web storage is the browser's localStorage, which keeps data until it is cleared, and sessionStorage, which lasts as long as the tab is open; IndexedDB is a larger database in the same browser. A widget writing a visitor ID to any of them is covered exactly like one setting a cookie, so no cookies does not mean no consent.
GDPR still governs the personal data inside the conversation, which needs its own lawful basis whatever the cookie answer is; our GDPR guide for chatbots covers that side. In the UK, the Privacy and Electronic Communications Regulations (PECR) apply the same rule with extra exceptions, covered further down.
What do chat widgets store before anyone clicks?
On a blank test page, 7 of the 10 widgets that ran wrote cookies or web storage within 15 seconds of loading, without a single click. Crisp, Tidio and PepoChat wrote nothing. Intercom, LiveChat and Smartsupp refused our test domain; the next section shows what they store where they are allowed.
We reused the test pages from our chat widget page speed measurement: one plain page per vendor with its official snippet and the public ID the vendor runs on its own site. Each page was loaded once in headless Google Chrome 155 with a fresh profile, from a US connection, on 19 October 2026 between 18:14 and 18:24 UTC. After the load event we waited 15 seconds without clicking, then recorded every cookie in the browser profile and every localStorage, sessionStorage, IndexedDB and Cache Storage entry, in the page and in every frame, including the vendors' cross-site iframes.
Because cookies behave differently on a bare IP address, every page ran twice, from 127.0.0.1 and from https://www.example.com mapped to the same machine, and both runs found the same items.
| Widget | Ran on the test page | Cookies on your domain | Third-party cookies | Web storage on your domain | Longest lifetime |
|---|---|---|---|---|---|
| PepoChat, default (preload on) | Yes | None | None | None; its chat frame loaded and stored nothing | Nothing stored |
PepoChat, data-preload="false" | Yes | None | None | None | Nothing stored |
| Crisp | Yes | None | None | None | Nothing stored |
| Tidio | Partly: the launcher never appeared | None | None | None | Nothing stored |
| Chatbase | Yes | chatbase_anon_id (browser session) | None | None | Browser session |
| Help Scout Beacon | Yes | None | None | localStorage: 1 key marking the launcher animation as shown | No expiry date |
| Gorgias | Yes | None | None | localStorage: 4 gorgias.* keys (AI agent state, language, version, timestamp) | No expiry date |
| Zendesk (messaging Web Widget) | Yes | None | None | localStorage: ZD-buid, ZD-suid, [integration ID].clientId | No expiry date |
| tawk.to | Yes | twk_uuid_[property ID] on the parent domain (180 days); twk_idm_key, TawkConnectionTime (browser session) | None | localStorage: 2 keys, one a signed token; sessionStorage: the page address | 180 days |
| HubSpot (tracking code) | Yes | __hstc, hubspotutk (180 days); __hssc (30 minutes); __hssrc (browser session) | __cf_bm (30 minutes) on 8 HubSpot domains | IndexedDB: hs-cta-interactions | 180 days |
| Zoho SalesIQ | Yes | [portal]-_zldp, [portal]-_zldt (400 days) | uesign (30 days), LS_CSRF_TOKEN (browser session) | localStorage: siq_embed (15 KB); sessionStorage: utsdb | 400 days |
| Intercom | No: domain not trusted | None | None | None | Nothing stored |
| LiveChat | No: license limited to its own domains | None | None | None | Nothing stored |
| Smartsupp | No: domain_not_allowed | None | None | None | Nothing stored |
Measured 19 October 2026 in Chrome 155, fresh profile per page, 15 seconds after the load event, no clicks. Your domain means the page's host or its parent domain; localStorage and IndexedDB entries have no expiry date.

The names matter more than the counts. Zendesk's in-product cookie policy files ZD-suid (20 minutes) and ZD-buid (no expiry) under Analytics, describing them as a session ID and a device ID for tracking events on pages that load the widget, and lists the clientId key as Essential. Zendesk's developer documentation says the messaging Web Widget stores essential, functional and analytics cookies by default, which matches what it wrote on our page before any click.
HubSpot's cookie page, last updated 9 September 2026, calls __hstc its main cookie for tracking visitors and says hubspotutk keeps track of a visitor's identity, each for six months, and lists __cf_bm as a necessary 30-minute bot-protection cookie from its CDN provider. HubSpot's row is the whole tracking code as HubSpot's own portal configures it, which also requested Facebook's pixel script on our page. HubSpot's chat cookie, messagesUtk, never appeared, because the chat window itself did not load on our page, as in the speed test.
tawk.to and Zoho SalesIQ set the longest-lived cookies: tawk.to's twk_uuid cookie for 180 days, written to the parent domain so every subdomain receives it, and Zoho's two _zld cookies for 400 days. Gorgias and Help Scout store interface state rather than identifiers: the AI agent's status, the language and a flag recording that the launcher animation has played.
Two empty rows need a caution. Tidio's launcher never appeared on our page, as in the speed test, so its row understates what Tidio stores where it runs. Crisp downloaded its full chat client and still wrote nothing in 15 seconds; it may store data once a visitor interacts, which we did not test.
What do Intercom, LiveChat and Smartsupp store?
Where they are allowed to run, Intercom, LiveChat and Smartsupp all write IDs or tokens before any click, and Tidio writes its widget state. On our test page the three stored nothing, because each refused a domain its account does not list: Intercom's API answered that the domain was not trusted, LiveChat's license accepted only its own domains and Smartsupp returned domain_not_allowed. PepoChat's allowed domains list is the same kind of guard.
To see what they store on a permitted site, we loaded each vendor's home page once with the same method and kept only items named after the widget, since those pages also run the vendor's own marketing tags.
| Widget, on the vendor's own home page | Cookies named after the widget | Web storage named after the widget | Longest lifetime |
|---|---|---|---|
| Intercom (intercom.com) | intercom-id-[app_id] and intercom-device-id-[app_id] (270 days); intercom-session-[app_id] (7 days) | localStorage: Messenger state; sessionStorage: 2 keys | 270 days |
| LiveChat (livechat.com) | __lc_cid, __lc_cst on accounts.livechatinc.com, a third-party domain (400 days) | In the chat frame: widget state, an auth token, a privacy-policy flag and a has-visited flag in localStorage; a tab ID in sessionStorage | 400 days |
| Smartsupp (smartsupp.com) | None named after the widget | localStorage: ssupp_[key] holding a session ID, an ID labelled vid and an opened flag | No expiry date |
| Tidio (tidio.com) | None named after the widget | localStorage: tidio_state_[key] (widget state, 9.6 KB) and tidio_state_[key]_cache (settings cache, 83 KB) | No expiry date |
Measured 19 October 2026, one load of each home page with the same method from a US connection, 15 seconds without clicks. Each of these sites runs its own consent banner, which may behave differently for visitors in the EU.
Are Intercom's Messenger cookies essential?
Intercom does not say, and its own documentation leaves the label to you. Intercom's Messenger cookies article, updated 10 August 2026, lists three first-party identifiers: intercom-id-[app_id], an anonymous visitor identifier that people receive as they visit your site; intercom-session-[app_id], which keeps access to previous conversations for one week by default; and intercom-device-id-[app_id], a device identifier kept for 270 days, renewed on each ping and used to prevent abuse. On how to categorise them, Intercom calls it "a legal and compliance decision that's yours to make".
Apply the test to each Intercom identifier. The visitor identifier is set on arrival, before anyone uses the Messenger, which is hard to fit into an exemption for a service the visitor requested. The session cookie is created when the Messenger boots, which is on page load by default, so it is only as defensible as that moment; booting on a click brings it closest to a conversation session. The device identifier serves a security purpose, but the Article 29 Working Party limited its security exemption to services the user explicitly requested, and this one is set before anyone opens the Messenger. On intercom.com we measured intercom-id as a 270-day cookie too; Intercom's article lists no fixed lifetime for it.
Intercom also documents a consent switch. With disabled: true in window.intercomSettings, the Messenger loads but does not boot and uses no cookies; calling Intercom('boot', { disabled: false }) after consent starts it. The script itself still downloads in that state, which costs page speed.
Which chat widget storage is strictly necessary, and which needs consent?
Storage needed to run a conversation the visitor started is the strongest candidate for the strictly necessary exemption; identifiers written on page load, analytics and anything used for advertising need consent. The UK ICO's guidance on the exceptions, finalised on 29 April 2026, says strictly necessary means the requested service could not be provided on a technical level without the storage, judged from the user's point of view rather than the site owner's.
The Article 29 Working Party, the EU regulators' body that preceded the EDPB, gave the closest example in its Opinion 04/2012 on the cookie consent exemption. The opinion describes user-input cookies that keep track of a user's input across a series of message exchanges with a service, tied to an action such as clicking a button, and exempts them for the length of a session, or a few hours in some cases. A chat conversation fits that description closely. The same opinion says a cookie with several purposes is exempt only if every purpose is, and that third-party cookies are usually not strictly necessary.
The ICO accepts the same logic for embedded videos in some circumstances. Its guidance says to configure an embed so it stores nothing when the page loads and to tell visitors that pressing play will use storage; once they press it, no consent is needed, because they were informed and asked for the content. A chat launcher can work the same way.
| What the widget stores or reads | Examples from our test | When it happens | Strictly necessary or consent? | Why |
|---|---|---|---|---|
| Session ID for a conversation the visitor opened | A session key written when the chat opens, such as PepoChat's echo_contact_session_ | After the visitor opens the chat | Likely strictly necessary | The visitor asked for the chat, as in the Working Party's user-input example; keep the lifetime close to the conversation |
| Visitor or device ID written on page load | hubspotutk, twk_uuid_[property ID], ZD-buid, chatbase_anon_id, intercom-id-[app_id] | Before any click | Consent | No service requested yet, and the ID recognises the browser across pages or later visits |
| Visit and session analytics | __hstc, __hssc, ZD-suid | Before any click | Consent (UK: statistical exception possible, with notice and an easy opt-out) | The chat works without it |
| Advertising pixels loaded by the same tag | Facebook's pixel script, requested by HubSpot's tracking code | Before any click | Consent, always | Regulators say no advertising purpose is exempt |
| Bot protection and fraud checks | __cf_bm (30 minutes) on HubSpot domains | On page load | Strictly necessary only if it protects a service the visitor requested | The Working Party's security exemption excludes services the user did not ask for; the ICO lists security and fraud prevention among exempt purposes |
| Interface state | Help Scout's animation flag, Gorgias's language key | Before any click | Likely consent in the EU (UK: appearance exception possible, with notice and an easy opt-out) | The Working Party exempts interface preferences only when the user chose them, for example by clicking a button |
| Reading a stored session on later pages | PepoChat with preload on, for visitors who chatted before | On page load | Arguable; turn preload off to make it click-only | Continuing a conversation the visitor started resembles a shopping basket, but the read happens before a click |
Based on Article 5(3), the Working Party's Opinion 04/2012 and the ICO's guidance finalised on 29 April 2026, all read on 19 October 2026. National regulators and courts decide individual cases, so treat this as the starting point of your own assessment.
How do you load a chat widget only after consent?
Keep the vendor's snippet off the page until the visitor accepts the category you filed it under, or until they click a placeholder chat button, and remove it again if consent is withdrawn. A click-to-load placeholder is a plain HTML button styled like a launcher that loads no third-party code; clicking it is an explicit request for the chat, the situation the exemption describes. Put one line next to the placeholder saying that opening the chat stores a session ID, as the ICO suggests for embedded videos.
A consent management platform (CMP) is the tool that shows your cookie banner and records each visitor's choices. Most CMPs expose a JavaScript event or property you can check before loading a script. The pattern below supports both triggers, using the CookiebotOnConsentReady event and Cookiebot.consent.preferences property from Cookiebot's developer documentation, with PepoChat as the example vendor.
<!-- Shown until the chat loads: plain HTML, no third-party code, nothing stored -->
<button id="chat-placeholder" type="button">Chat with us</button>
<p id="chat-note">Opening the chat loads our chat provider, which keeps a session ID in your browser.</p>
<script>
(function () {
var placeholder = document.getElementById("chat-placeholder");
var note = document.getElementById("chat-note");
var loadedBy = null; // "click" or "consent"
// Put your vendor's snippet in here. Example: PepoChat with preloading off.
function loadChatWidget(reason, openNow) {
if (loadedBy) return;
loadedBy = reason;
placeholder.hidden = true;
note.hidden = true;
if (window.EchoWidget) {
// Loaded earlier and removed: bring it back without a second script tag.
window.EchoWidget.init({});
if (openNow) window.EchoWidget.show();
return;
}
var s = document.createElement("script");
s.src = "https://widget.pepochat.com/widget.js";
s.async = true;
s.setAttribute("data-organization-id", "YOUR_ORGANIZATION_ID");
s.setAttribute("data-preload", "false");
s.onload = function () {
if (openNow && window.EchoWidget) window.EchoWidget.show();
};
document.body.appendChild(s);
}
function removeChatWidget() {
if (window.EchoWidget) window.EchoWidget.destroy();
loadedBy = null;
placeholder.hidden = false;
note.hidden = false;
}
// 1. Click to load: the visitor asks for the chat, so it loads and opens.
placeholder.addEventListener("click", function () {
loadChatWidget("click", true);
});
// 2. Consent: load on every page once the visitor accepts the category
// you filed the widget under (Cookiebot's "preferences" here).
function applyConsent() {
var accepted = !!(window.Cookiebot && window.Cookiebot.consent && window.Cookiebot.consent.preferences);
if (accepted) loadChatWidget("consent", false);
else if (loadedBy === "consent") removeChatWidget();
}
window.addEventListener("CookiebotOnConsentReady", applyConsent);
applyConsent(); // the visitor's choice may already be known
})();
</script>
Swap the body of loadChatWidget for your vendor's snippet and the consent check for your CMP's equivalent. Cookiebot can also gate a snippet without custom code: it runs script tags marked type="text/plain" with a data-cookieconsent attribute once the visitor's choice allows that category.
Some vendors have their own switch, which is cleaner than blocking the script. Zendesk's messaging Web Widget accepts zE('messenger:set', 'cookies', 'none'), which hides the widget and deletes its local and session storage, or 'functional', which keeps everything except analytics. Intercom has the disabled setting described above. PepoChat has no consent API of its own: data-preload="false" keeps the chat frame from loading until the launcher is clicked, and EchoWidget.destroy() and EchoWidget.init() remove and restore the widget, as the behavior and API docs describe.

When a visitor withdraws consent, removing the widget stops new storage, but your page cannot delete what a cross-site chat frame already stored, because it has no access to that storage. Short server-side session lifetimes limit what such a leftover ID is worth.
What does PepoChat store, and does it need consent?
PepoChat writes nothing to your site's cookies or storage, and nothing to its own frame's storage until a visitor first opens the chat; whether your policy treats the chat as strictly necessary is still your call. Both the loader's source code and the measurement above confirm it: no cookie or storage on the page in either mode, and an empty chat frame in the default mode.
The PepoChat chat runs in a frame on widget.pepochat.com and keeps its state in that frame's localStorage. When a visitor opens the chat, it can write three keys: the session ID (echo_contact_session_ plus your workspace ID), a read-up-to timestamp for the unread badge (echo_unread_seen_ plus the session ID), and, if you set a Privacy policy link in Widget Customization and the visitor dismisses the one-line notice that links to it, that link (pepochat_privacy_notice_dismissed), so the notice stays hidden. The privacy page in our docs lists everything the widget collects.
PepoChat visitor sessions last 24 hours and are extended while the visitor keeps chatting; a session that never became a conversation is deleted a day after it expires. The stored session ID stays in the browser until it is replaced or cleared, but the server stops accepting it once the session has expired.
Two details belong in your assessment. With preload on, the default, a visitor who has chatted before has the stored session ID read, and the badge timestamp updated, on later pages, so the conversation and the unread badge carry over; with data-preload="false" nothing is loaded or read until the launcher is clicked. And when the chat opens, the session is created with technical details your team sees as visitor details: browser and operating system, screen and viewport size, language, time zone, whether cookies are enabled and the page's origin. The EDPB counts a script reading such details from the device as gaining access, so count them as part of what the chat does, not as free.
If your policy is to gate every third-party script anyway, the consent pattern above works with PepoChat as written; the install docs list every script attribute.
Do the UK rules differ from the EU rules?
Yes, a little, since the Data (Use and Access) Act 2025 amended PECR. The ICO's guidance lists five exceptions: communication, strictly necessary, statistical purposes, appearance and emergency assistance. The statistical and appearance exceptions apply only if you give clear information and a simple, free way to object. The EU Directive keeps just the first two.
For a chat widget on a UK site, those exceptions can cover aggregate widget analytics used to improve the service, and interface preferences such as a remembered language, with notice and an opt-out instead of consent. The ICO is explicit that the statistical exception does not allow tracking or monitoring individual visitors and that no advertising purpose qualifies, so identifiers used to recognise individual visitors, like several in our first table, still need consent. The ICO also puts the duty on the site owner: if you deploy another company's technology, you must understand what it does and make sure it complies.
What to do next
Open your site in a private window, check the Application panel of Chrome's developer tools before clicking anything, and list what your widget writes; then compare the list with the decision table and choose consent gating or click-to-load. The script tag guide shows where the loader goes on each site builder, and the chatbot disclosure laws post covers the other notice a chat needs. To check PepoChat's behaviour yourself, start a free workspace and inspect the chat frame's storage before and after opening it; every feature is on the free plan.
Frequently asked questions
- Does a live chat widget need cookie consent under GDPR?
- Under the EU ePrivacy Directive, which sits alongside GDPR, a chat widget needs consent for anything it stores or reads on the visitor's device unless that is strictly necessary for a service the visitor requested. Storage written before a visitor opens the chat usually fails that test; a session created when the visitor opens it is easier to defend. This is general information, not legal advice.
- Is localStorage covered by cookie consent rules?
- Yes. Article 5(3) of the ePrivacy Directive covers storing or reading any information on a user's device, and the EDPB's Guidelines 2/2023, adopted in final form on 7 October 2024, confirm it is not limited to cookies. The UK ICO's guidance names localStorage and sessionStorage too. A widget writing a visitor ID to localStorage needs the same assessment as a cookie.
- Are Intercom cookies strictly necessary or functional?
- Intercom leaves that label to you. Its Messenger cookies article, updated 10 August 2026, lists an anonymous visitor identifier set as people visit, a one-week session cookie and a 270-day device identifier used against abuse. The visitor identifier is set before anyone uses the Messenger, which is hard to call strictly necessary. Intercom's disabled setting keeps the Messenger from booting until consent.
- How do I load a chat widget only after cookie consent?
- Keep the vendor's snippet off the page and insert it from your consent manager once the visitor accepts the category you filed the chat under; with Cookiebot, listen for the CookiebotOnConsentReady event and check Cookiebot.consent.preferences. You can also show a plain chat button that loads the widget only when clicked. Remove the widget again if the visitor withdraws consent.
- Does PepoChat set cookies on my website?
- No. PepoChat's loader sets no cookies and writes nothing to your site's storage, which we confirmed in its code and on a test page on 19 October 2026. The chat frame keeps a session ID in its own localStorage only once a visitor opens the chat, and sessions last 24 hours, extended while the visitor chats. Whether that needs consent is your assessment.
- Which chat widgets store data before a visitor clicks?
- In our 19 October 2026 test on a blank page, Chatbase, Gorgias, Help Scout Beacon, HubSpot's tracking code, tawk.to, Zendesk and Zoho SalesIQ wrote cookies or browser storage within 15 seconds without a click. Crisp, Tidio and PepoChat wrote nothing there. Intercom, LiveChat and Smartsupp refused our test domain but stored identifiers on their own home pages.
Try this on your own site in ten minutes
PepoChat includes every feature on the free plan — 200 AI replies and 5 knowledge sources a month, no credit card.
Keep reading
Chatbase vs PepoChat: Which AI Support Agent Fits Your Team in 2026?
An honest side-by-side of Chatbase and PepoChat on pricing, free plan or trial, sources, handoff, booking, actions, channels and voice, and a pick by team type.
Intercom Fin Pricing Explained, and What a Flat-Plan Alternative Costs
What Intercom Fin's $0.99 per outcome adds up to once you count resolutions and seats, with a worked 2,000-conversation example and when a flat plan wins.
