# Web Worker & Tabs (/docs/worker-and-tabs)



## Tokens live in a Web Worker [#tokens-live-in-a-web-worker]

By default every request runs inside a Web Worker. The token is stored there and attached there, so page JavaScript, including a script injected through XSS, can't read it.

<TokenDemo />

There is nothing to set up: the worker is bundled inline, with no extra file to host and no bundler plugin to add.

### When it falls back [#when-it-falls-back]

The client silently uses the main thread instead, with identical behaviour, when:

* you pass `worker: false`, or the code runs on a server (SSR, Node)
* the browser blocks the worker. Your Content Security Policy must allow `worker-src 'self' blob:`
* `extractTokens` or `buildRefreshBody` is a **function**. Functions can't be sent into a worker; use their [object forms](/docs/token-refresh#custom-token-shapes)

Check what you got with `api.isWorker`.

### What it can't protect [#what-it-cant-protect]

An injected script can still *use* your session. It can call `api.get(...)` just like your own code, so worker isolation stops token theft, not XSS itself. Also, `storage: "local"`, `"session"` and `"cookie"` put the token where page JavaScript can read it. Keep the default `"memory"` to get the full benefit.

## Tabs stay in sync [#tabs-stay-in-sync]

Clients with the same `storageKey` talk to each other over `BroadcastChannel`:

* **Log out in one tab**: every tab logs out.
* **Log in in one tab**: the others pick up the session (when storage is shared: `"local"` or `"cookie"`).
* **Refresh**: tabs that share a session take turns through the Web Locks API. When one tab has already refreshed, the next adopts its new tokens instead of spending the refresh token again. This matters when your server rotates refresh tokens and treats reuse as theft.

Two independent apps on one origin? Give each its own `storageKey`:

```ts
const adminApi = createClient({ storageKey: "admin" });
const shopApi = createClient({ storageKey: "shop" });
```

Turn syncing off with `multiTab: false`.
