Privacy & consent
Gate the Grovs Web SDK on user consent, and see what it collects.
Gating collection on consent
Tracking is on by default. To gate it behind a cookie banner, configure with requireConsent: true and grant consent when the banner is accepted:
await Grovs.configure({ apiKey: "your-api-key", requireConsent: true });
// Nothing has been stored on the device or sent. Events tracked meanwhile are
// held in memory and delivered once consent arrives.
await Grovs.grantConsent();configure resolves false while consent is pending. grantConsent() moves anything tracked meanwhile into durable storage, authenticates and resolves true on success. configure captures the URL's link token in memory, so a router that cleans the query string during the banner doesn't lose the deep link.
Withdrawing consent
Grovs.reset();reset() clears every stored identifier, the session and queued events for all projects on the origin, and stops tracking. It doesn't re-authenticate on its own, by design. To start again, call configure (then grantConsent() if you require consent). A reset in one tab stops other tabs sending as the erased visitor.
Disabling the SDK
Grovs.setEnabled(false);Disabling stops the SDK rather than muting it:
- Timers are cleared and lifecycle listeners detached.
- The History patch for screen tracking is removed, or left inert if another library has wrapped it since.
- In-app messages and the smart banner stop.
- Screen alias updates are held.
setEnabled(true) starts it again and re-runs an initialization interrupted mid-retry.
What the SDK collects
| Data | When | Why |
|---|---|---|
User agent, screen size, time zone, language, WebGL vendor and renderer strings, your appVersion, the SDK version, and a session id | When configure authenticates | A device fingerprint used to match deferred deep links |
A visitor identifier stored in a cookie and in localStorage | Same | Recognizing the visitor across visits |
| User identifier and attributes | Only if you set them | Showing users in the dashboard |
| Installs, reinstalls, opens, time spent, reactivations | Automatically | Attribution and analytics |
| Custom events and screen views, with your properties and tags, a session id, and the attribution path the visit arrived on | When you call track / trackScreenView, and through automatic screen tracking | Analytics |
| Purchases | When you call logCustomPurchase | Revenue analytics |
| In-app message views, clicks, dismissals and answers, with the campaign id; campaign sync requests | When a campaign is shown or the SDK syncs | In-app messages and their reports |
The page path and the link data you passed to setLinkData(); smart_banner_view, smart_banner_click and smart_banner_dismiss events | On mobile browsers, when a smart banner shows | The smart banner |
With the default requireConsent: false, collection starts at configure. With requireConsent: true, nothing is written to the device or sent until grantConsent().
The smart banner stores dismissals in localStorage (grovs_smart_banner_dismissed) and caches configuration and links in sessionStorage (grovs_sb:* keys). The web SDK never reads the clipboard. Stored state is keyed per project and testEnvironment; the visitor identifier is shared across projects on the origin.
Safari
The visitor identifier goes in both a cookie and localStorage, because Safari's Intelligent Tracking Prevention caps script-written cookies at seven days. That covers visitors returning within the window. ITP can still evict storage for dormant visitors, so Safari install counts carry a small known over-count.
Logs
Set the level with debugLevel in configure. Default "error"; an unrecognized debugLevel falls back to it.
Grovs.setDebugLevel("info") changes the configured client's level at any time. A value set before configure doesn't carry over, and an unrecognized value silences every log line, so pass only "info", "warn" or "error". Warnings (a rejected event name, an ignored alias pattern) print only at "warn" or "info".