Privacy, cookies and consent
What the Roblox module and the web SDK collect and store, and what you should do before you ship them.
This page explains what RoChart collects, so you can describe it to your players and decide what you need to do. It isn't legal advice: if you're unsure, check with whoever handles privacy for your studio. Your game also has to follow Roblox's own terms and policies.
In your game
The Roblox module runs on your game server. It stores nothing on players' devices: no cookies, no local storage. A small client script only reports the player's platform to the server.
Each event carries:
- the player's UserId, and the session, server and place ids,
- platform (
Computer,Phone,Tablet,Console,VR), country fromLocalizationServiceand locale (player.LocaleId), - on join: how they joined (join source, referrer UserId, source place, launch data and campaign), account age in days, Premium, server type and place version,
- on purchases: the product, its type and the Robux spent,
- whatever properties you add with
trackandsetUserProperties.
The player's username and display name are kept on their profile. Roblox doesn't share age, gender, email or any contact details with games, and RoChart doesn't ask for them. Events come from Roblox's servers, so RoChart never sees a player's IP address or device.
What you should do:
- Don't send personal information. Keep chat messages, real names and anything players type out of event properties. If you send feedback, it's text a player chose to send you, so keep it to that.
- Handle deletion requests. When Roblox asks you to delete a player's data (the "Right to erasure" message), find the player under People by UserId, then ⋯ → Delete person. That removes their profile, properties and ids. Their past events are kept but no longer linked to a profile. Also remove the UserId from anything you send it with yourself.
Websites
The rest of this page is about the browser SDK, for example on your game's website.
What's stored in the visitor's browser
By default RoChart sets no cookies. It keeps a small record in localStorage under a key starting with nd_. The record holds:
- an anonymous visitor ID (a random value, not derived from anything about the person),
- the current session ID and when it started,
- the user's ID, if your site calls
identify, - feature flag values, if you use flags,
- whether the visitor opted out.
The persistence option in init decides where that record lives:
persistence | Stored in the browser | Visitors across page loads |
|---|---|---|
'localStorage' (default) | localStorage and sessionStorage, no cookies | Recognised |
'cookie' | A first-party cookie (SameSite=Lax, Secure on https, 1 year), plus sessionStorage | Recognised |
'memory' | Nothing | Every page load is a new anonymous visitor |
Under EU and UK law (GDPR and ePrivacy/PECR), storing an ID in localStorage needs the same consent as a cookie. Switching to localStorage doesn't avoid the consent requirement.
What's sent with each event
The script captures page views and page leaves on its own, plus whatever you send with capture. Each event carries:
- the page URL, path, query string and referrer,
- screen and window size,
- the anonymous visitor ID and session ID (and the user's ID if you called
identify), - any properties you added.
On the server, RoChart works out the browser, operating system and device type from the user agent. It takes the country from your CDN's country header (for example Cloudflare's). IP addresses aren't stored.
What you need to do
- Mention RoChart in your privacy policy. Say you use analytics to understand how your site is used. List what's collected (the list above) and that it's stored in the visitor's browser.
- If you have visitors in the EU or UK, ask for consent before storing anything. Either load in memory mode and switch once they agree, or only start RoChart after they agree. Both are shown below.
- Don't send personal data you don't need. Keep emails, names and phone numbers out of event properties and out of URLs (for example
?email=in a query string). If youidentifypeople, use your own internal user ID rather than an email address where you can. - Handle deletion requests. Find the person under People, then ⋯ → Delete person. That removes their profile, properties and IDs. Their past events are kept but no longer linked to a profile.
Asking for consent
init can only be called once per page load, so pick the storage mode when the page loads.
Count visits without storing anything until they agree. Visitors who decline still show up in page views, but each page load counts as a new visitor:
const consented = localStorage.getItem('analytics-consent') === 'yes'
rochart.init('<project token>', { persistence: consented ? 'localStorage' : 'memory' })
// in your banner's "Accept" handler
localStorage.setItem('analytics-consent', 'yes') // full tracking from the next page loadOr don't load RoChart at all until they agree. Nothing is sent before consent:
function startAnalytics() {
rochart.init('<project token>')
}
if (localStorage.getItem('analytics-consent') === 'yes') startAnalytics()
// in your banner's "Accept" handler
localStorage.setItem('analytics-consent', 'yes')
startAnalytics()If you installed with the script tag, the global may be called something else (for example tracker). The calls are the same.
Letting people opt out later
rochart.optOut() stops all capturing in that browser and drops anything not yet sent. rochart.optIn() turns it back on, and rochart.hasOptedOut() tells you which state it's in. The opt-out is remembered in the same storage as the visitor ID, so it lasts as long as that does (in memory mode, only until the page reloads).
Server-side events
Events your backend sends (with the Node SDK or /i/batch) don't touch the visitor's browser, so there's no cookie question. The same rule about personal data applies: send only what you need.
Your team's sign-in
People who sign in to RoChart get a session cookie, like any web app. That's on the RoChart app only; players and visitors to your site never get it.