Visitor recognition
How the widget recognizes returning visitors and the consent that governs the visitor cookie.
The widget tracks two layers of identity:
- Visitor: a stable anonymous identifier. Present for every visitor, signed-in or not.
- Contact: the identified person behind the visitor, created or matched by identification.
The visitor cookie
When the widget boots it reads the visitor's anonymous ID, or create one on the first visit, and stores it under the key assistify.<widgetId>.vid on the host's own origin:
| Storage | Notes |
|---|---|
| Cookie | Path=/, SameSite=Lax, Secure on HTTPS, Max-Age ~6 months (renewed on each return visit). Written by default, removed only when consent is explicitly denied. |
| localStorage | Mirror for cross-tab consistency. |
The server uses this value to bind the visitor's anonymous session to a Contact once one exists. Subsequent visits restore the conversation list as long as the cookie survives.
Read the current ID:
widget.user.getVisitorId(); // 'anon_aB3xY...' or nullnull means there is nothing to read yet, or nowhere to read it from. The runtime create the ID on its first boot, so before that point (or before load() under autoload: false) no ID exists, and storage can be unavailable in private browsing, in a sandboxed iframe, or in a browser with storage blocked. An undecided consent state does not return null: the ID is stored by default.
Consent and storage
The visitor ID is a strictly-necessary functional cookie: it keeps the chat consistent across pages and lets a returning visitor's earlier conversation be restored. So it is persistent by default, as with other live-chat tools, only an explicit deny moves the widget to a session-scoped ID.
| Consent decision | Where the ID lives | Survives |
|---|---|---|
granted or unknown (default) | Cookie + localStorage | Across visits (~6 months) |
denied | sessionStorage only | The current tab, gone when it closes |
In session-only mode the chat keeps working for the current visit, but the visitor is not recognized on the next one.
Grant or withdraw at runtime:
window.Assistify.setConsent(true); // re-enable: the visitor ID is promoted to cookie + localStorage
window.Assistify.setConsent(false); // opt out: cookie + localStorage deleted, falls back to a session-only ID
window.Assistify.getConsent(); // 'granted' | 'denied' | 'unknown'Both calls are safe at any time, including before the widget has booted: the loader records the decision immediately, and boot honors it, so an early setConsent(false) means the persistent cookie is never written at all.
The widget also reads the host page's IAB TCF v2.2 signal (Purpose 1). When a consent management platform is present, its decision wins, so the visitor is never asked twice.
To gate the loader script and all network activity behind consent instead, mount with autoload: false and call widget.load() from your CMP's grant callback. See Assistify SDK → Deferred boot.
Your privacy policy
Your website is the controller of chat visitor data, Assistify processes it on your behalf. Two published notices describe the chat to your visitors in plain language:
- Chat Privacy Notice: what the chat collects, why, how long it is kept, and visitor rights.
- Cookie and Storage Notice: the visitor cookie and every browser-storage item the widget writes.
Mention the chat in your website's privacy policy and link both notices from it (or from your cookie information). If your website runs a cookie banner, no extra wiring is needed: the widget reads its TCF signal automatically, and setConsent covers custom banners.
For your data-protection records, the Data Processing Agreement you accepted at registration and the current sub-processor list are published at those URLs.
Clearing a visitor
Two primitives clear this stored identity:
reset()is the logout primitive: it wipes the server session, the cookie, the localStorage and sessionStorage mirrors, and the identity surfaces the loader left on the page, then re-boots anonymous. Call it on logout so the next visitor on a shared browser starts fresh.destroy()is the teardown primitive (for example an SPA leaving a chat route): it stops the runtime but leaves storage intact, so a latermount()recognizes the returning visitor.
For the exact list of what reset() clears, see JavaScript API → reset().