2026-08-29 11:46:20 +03:00
---
name: rudder-web-sdk
description: Use when working with the Rudder TypeScript/JavaScript SDK (@rudder/js -sdk) — the browser/player-facing SDK for the Rudder LiveOps platform. Covers client setup, device/custom auth, observable domains (player, inventory, catalog, stores, remote config, storage), leaderboards, quests, battle pass, scenario effects, and error handling. Load this whenever code imports from @rudder/js -sdk or RudderClient appears.
---
# Rudder Web SDK (@rudder/js-sdk)
Browser-facing player SDK for the Rudder LiveOps platform. Source of truth:
`liveops-web-sdk/src` (generated wire types in `src/generated` come from the
gateway's apigen — never edit them by hand).
## Install
Published to a private registry, not npmjs. Point the `@rudder` scope at it in
`.npmrc` (anonymous read, no token):
```
@rudder:registry=https://hub.rudder.build/api/packages/rudder/npm/
```
``` bash
npm install @rudder/js-sdk
```
ESM + CJS + `.d.ts` ; `type: module` ; zero runtime dependencies.
## Init
``` ts
import { RudderClient } from '@rudder/js-sdk' ;
const client = new RudderClient ( {
baseUrl : 'https://api.rudder.build' , // required
projectKey : 'your-project-key' , // required
// tokenStore?: TokenStore — default: localStorage, in-memory fallback
// requestTimeoutMs?: number — default 10000
// syncIntervalMs?: number — revision poll, default 30000 (±20% jitter)
// onEffectError?: (error) => void — default console.error
2026-09-04 14:08:48 +03:00
// runtime?: { loginEvent? } — advanced, see reference/scenarios.md
2026-08-29 11:46:20 +03:00
} ) ;
```
`client` is generic: `RudderClient<TConfig extends Record<string, unknown>>`
types `client.remoteConfig.get()` . Missing `baseUrl` /`projectKey` throws
`RudderError` with `code: 'sdk/invalid-options'` from the constructor.
Call `client.dispose()` on unmount/HMR to stop the sync poll, wait timers, and
drop cached state.
## Auth essentials
``` ts
await client . auth . loginWithDevice ( { region , language , nickname } ) ; // device id auto-generated/persisted
await client . auth . loginWithCustom ( { customData , region , language , nickname } ) ;
client . auth . logout ( ) ;
client . auth . isAuthenticated ; // boolean
client . auth . onAuthStateChange ( cb ) ; // fires immediately, returns unsubscribe
```
Tokens are saved to the `TokenStore` automatically. The transport injects
`Authorization: Bearer <token>` , retries GETs, and single-flight refreshes on
401; a failed refresh clears tokens and emits `signed-out` . Details:
[reference/auth.md ](reference/auth.md ).
## Client surface (all domains that exist)
Every member below is a property on `RudderClient` . There is no UGC, wallet
service, or standalone economy service in this SDK — wallets live on
`client.player.data.wallets` , and purchases go through `client.stores` .
| Area | Access | Kind |
|---|---|---|
| Auth | `client.auth` | service |
| Player profile + wallets | `client.player` | observable `SyncedState<PlayerProfile>` |
| Inventory (catalog-merged) | `client.inventory` | observable `SyncedState<InventoryItem[]>` |
| Catalog | `client.catalog` | observable `SyncedState<Map<string, CatalogItem>>` |
2026-09-06 22:39:03 +03:00
| Stores / purchases | `client.stores` + `client.stores.purchase(slug, offerSlug, opts?)` | observable `SyncedState<ShopHandle[]>` |
2026-08-29 11:46:20 +03:00
| Remote config | `client.remoteConfig` + `.get(key, default?)` | observable, typed |
| Player storage | `client.storage` + `.save(items)` / `.delete(type)` | observable + mutations |
| Project storage | `client.projectStorage` + `.save(items)` | observable + mutation |
| Leaderboards | `client.leaderboards.findBySlug(slug)` | service → cached handle |
| Battle pass | `client.battlePass` | plain service (no live sync) |
| Quests | `client.quests` | plain service (no live sync) |
| Scenario effects | `client.effects.on*` | event subscriptions |
## Observable domains — the shared pattern
`player` , `catalog` , `inventory` , `remoteConfig` , `storage` ,
`projectStorage` , and `stores` all extend `SyncedState<T>` :
- `.data: T | undefined` , `.status: 'idle' | 'loading' | 'ready' | 'error'` ,
`.error?: Error`
- `onChange(cb: (snapshot: SyncedSnapshot<T>) => void): () => void` — fires
immediately with the current snapshot; maps onto React `useSyncExternalStore`
- `load(): Promise<T>` — deduplicated, no-op when ready
- `reload(): Promise<T>` — forced refetch
`remoteConfig` , `player` , `stores` , and `catalog` are warmed once at login;
`inventory` , `storage` , and `projectStorage` load on first use. All observable
domains are then kept fresh by a revision poll every 30 s (±20% jitter);
polling pauses while the tab is hidden. Mutations (purchases, storage writes,
scenario callbacks) invalidate affected domains immediately. Call `reload()`
when you need a freshness guarantee.
`leaderboards` , `battlePass` , and `quests` are NOT observable — refetch
explicitly after mutations.
## Errors
All SDK errors extend `RudderError` (optional machine-readable `code` ):
- `RudderNetworkError` — fetch failed / timeout (`error.cause` holds the original)
- `RudderHttpError` — non-2xx, carries `status` , `statusText` , `body` , `code`
- `RudderAuthError extends RudderHttpError` — 401 after failed refresh; tokens
already cleared, `signed-out` already emitted
- `RudderError` with `code: 'sdk/invalid-options'` (`SDK_ERROR_INVALID_OPTIONS` )
— constructor validation
Server error codes (`RudderErrorCodes` , from `src/generated/errors.ts` ):
`early_completion` , `forbidden` , `level_not_reached` , `node_not_active` ,
`objectives_incomplete` , `run_expired` , `run_not_active` ,
`scenario_not_active` , `unknown_run` . Compare with
`error.code === RudderErrorCodes.runExpired` .
## Reference files
- [reference/auth.md ](reference/auth.md ) — login flows, options, token store, session lifecycle
- [reference/player.md ](reference/player.md ) — profile + wallets (`PlayerProfile` , `Wallet` )
- [reference/inventory.md ](reference/inventory.md ) — inventory domain, merged `InventoryItem` , catalog
- [reference/stores.md ](reference/stores.md ) — `ShopHandle` /`OfferHandle` , purchases, idempotency
- [reference/remote-config.md ](reference/remote-config.md ) — typed `get()` , value types, overrides
- [reference/storage.md ](reference/storage.md ) — player + project storage, limits
- [reference/leaderboards.md ](reference/leaderboards.md ) — handles, submit, list
- [reference/quests.md ](reference/quests.md ) — list/claim/reportProgress, `QuestMetrics`
- [reference/battlepass.md ](reference/battlepass.md ) — progress, XP, claims, premium
- [reference/scenarios.md ](reference/scenarios.md ) — effects, scenario runtime, wait/quest/battlepass nodes