---
title: Manage user IDs in browser-based SDKs
slug: feature-experimentation/docs/manage-user-ids-in-browser-sdks
docTags: 
createdAt: 2026-08-05T20:39:58.000Z
---

Feature Experimentation requires a consistent and unique user ID to assign users to variations and ensure they receive a consistent experience across sessions and devices.

For browser-based SDKs like [JavaScript](docId:8PWUc59E_yQaRlOmUc5JA) and [React](docId\:qfwx3wCoS4mwpP0g7nIez), you are responsible for generating and persisting the user ID. The following sections describe how to implement that logic using cookies, local storage, and CDN tools.

:::hint{type="info"}
**Note**
These strategies apply only to browser-based SDKs. For server-side or mobile SDKs such as Swift, Android, or Python, see [Handle user IDs](docId\:j0PPoMJWYbz04K76EKLUI) and platform-specific documentation.
:::

## Choose a storage strategy

### Store user IDs in cookies

Cookies are the most common way to persist user IDs across sessions.

- **Persistent cookies** – Remain on the browser until they expire. Use these to preserve the user ID across visits.
- **Session cookies** – Cleared when the browser session ends. Use when long-term tracking is not necessary or consent has not been given yet.

:::hint{type="info"}
**Note**
Using session cookies may increase your monthly active users (MAUs) consumption. See [Monitor MAUs](docId:7AHMiX4UcWP1iNUY6X17X).
:::

When using cookies, ensure they are scoped correctly across domains and use secure attributes.

### Use local storage for same-origin persistence

`localStorage` lets you persist a user ID across sessions, but only for the same domain.

Use `localStorage` when

- your application is limited to a single domain.
- you do not need to share the user ID across subdomains.

Avoid it if you require cross-subdomain persistence or need to read the ID server-side.

### Manage user IDs at the edge with a CDN

Use edge logic provided by your CDN to assign or inject user IDs.

- **Edge worker** – Runs a function on the edge that will add a user ID cookie to the HTTP response headers.
- **Edge-side includes (ESI)** – Serves a JavaScript snippet that generates and persists a user ID.

**Considerations**

- Optimize edge logic for performance.
- Ensure cookie management at the edge complies with your organization’s privacy and security policies.
- Check your CDN’s capabilities for header or cookie manipulation.

### Privacy considerations

- Be transparent about how you use `userId`s in experiments.
- Use a cookie banner or other consent mechanism to capture and verify consent.
- Check for consent before storing persistent identifiers.

## Implement user ID logic with code samples

### With NPM packages (`js-cookie` and `uuid`)

```javascript
import {v4} from 'uuid';
import cookies from 'js-cookie';

function getOptimizelyId() {
  const visitorId = cookies.get('visitorId') || v4();
  cookies.set('visitorId', visitorId, {expires: 365, domain: '.example.com'});
  return visitorId;
}
```

### Without NPM packages (with custom cookie functions)

```javascript
function getOptimizelyId() {
  const visitorId = getCookie('visitorId') || uuidv4();
  setCookie('visitorId', visitorId, 365, '.example.com');
  return visitorId;
}

function getCookie(cname) {
  let name = cname + "=";
  let decodedCookie = decodeURIComponent(document.cookie);
  let ca = decodedCookie.split(';');
  for (let i = 0; i < ca.length; i++) {
    let c = ca[i].trim();
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

function setCookie(cname, cvalue, exdays, domain) { 
  const d = new Date();
  d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
  let expires = "expires=" + d.toUTCString();
  document.cookie = `${cname}=${cvalue}; ${expires}; domain=${domain}; path=/`;
}

function uuidv4() {
	return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => 
  	(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  );
}
```

### With local storage

```javascript
import { v4 } from "uuid";

function getOptimizelyId() {
  const visitorId = localStorage.getItem('visitorId') || v4();
  localStorage.setItem('visitorId', visitorId);
  return visitorId;
}
```

## Best practices

- **Provide a clear name** – Avoid using "optimizely" in the cookie name to reduce ad blocker interference.
- **Use secure cookie attributes** – Set `Secure` and `SameSite` attributes where appropriate.
- **Centralize ID logic** – Create a single utility or service that handles userId generation and storage.
- **Check before generating** – Avoid overwriting an existing userId.
- **Refresh expiration** – Extend the cookie expiration date for returning users to keep their ID active.
- **Comply with regulations** – Ensure your storage logic integrates with your consent mechanism and privacy policy.
