> ## Documentation Index
> Fetch the complete documentation index at: https://docs.westyx.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# React SDK - Configuration

> NexusConfig field reference and NexusProvider props for the React SDK.

The SDK is configured via the `NexusConfig` interface, passed to `<NexusProvider config={...}>`. The provider also accepts a few props that control its render lifecycle.

## `NexusConfig`

```tsx theme={null}
<NexusProvider config={{
  baseUrl: 'https://<slug>.westyx.dev',  // required
  apiKey:  'wxp_...',                // required
  ttlMs:   60_000,                       // optional, default 60 000 ms
  logger:  myLogger,                     // optional
}}>
```

| Field                  | Type                   | Default       | Description                                                                                                                                                                                                                                                         |
| ---------------------- | ---------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `baseUrl`              | `string`               | -             | Full service URL, e.g. `https://<slug>.westyx.dev`. The slug embedded in the host is also used as the `Host` header (Double-Gate requirement).                                                                                                                      |
| `apiKey`               | `string`               | -             | Raw `wxp_...` key. Sent in the `X-Nexus-API-Key` header on both `/v1/sync` and `/v1/stream`. The SDK uses fetch-based SSE (not the browser `EventSource` API), so the key travels as a header - never as a `?key=...` query parameter. *(header-only since v0.4.1)* |
| `ttlMs`                | `number`               | `60_000`      | Local cache TTL in milliseconds. After this elapses, the next read triggers a one-shot background refresh while still serving the stale cache.                                                                                                                      |
| `logger`               | `NexusLogger`          | `NOOP_LOGGER` | Optional diagnostic logger. Defaults to a no-op (silent).                                                                                                                                                                                                           |
| `streamObserver`       | `NexusStreamObserver?` | `undefined`   | *(v0.2.0)* Optional structured-callback observer for SSE lifecycle events. See [Stream observer](stream-observer).                                                                                                                                                  |
| `sseReconnectCooldown` | `number \| number[]`   | `undefined`   | Schedule for reconnecting SSE after falling back to TTL polling. Unit: **minutes**. `undefined` = default `[5, 10, 20, 40, 60]` min exponential. Single number = fixed interval. Array = custom schedule (stays at last value). *(v0.6.0)*                          |

## `NexusProvider` props

| Prop              | Type                          | Description                                                                                                      |
| ----------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `config`          | `NexusConfig`                 | Required. Passed to `NexusClient.create()`.                                                                      |
| `children`        | `ReactNode`                   | Rendered after the initial sync resolves.                                                                        |
| `loadingFallback` | `ReactNode`                   | Optional. Rendered while the initial sync is in flight. Defaults to `null`.                                      |
| `onError`         | `(error: Error) => ReactNode` | Optional. Called when the initial sync fails. If omitted, the error is thrown so an Error Boundary can catch it. |

## API key types

| Prefix    | Access                                                                          | Browser-safe?                  |
| --------- | ------------------------------------------------------------------------------- | ------------------------------ |
| `wxs_...` | Full - all configs, all secrets, all flags                                      | rejected at runtime by the SDK |
| `wxp_...` | Restricted - public configs and flags; `useSecret()` always returns `undefined` | yes                            |

Browser SDKs **must** use a `wxp_...` key. The SDK enforces this in three places:

1. **`PublicApiKey` branded type** - when typed strictly, TypeScript prevents passing a plain `string` without `assertPublicKey()`
2. **Runtime guard** - throws `Error('Browser SDKs require a public key (wxp_...)')` before any network call
3. **Backend enforcement** - a request carrying an `wxs_...` key in the `X-Nexus-API-Key` header against a browser/public surface is rejected with `400 Bad Request`

```tsx theme={null}
import { assertPublicKey } from '@westyx-nexus/sdk-react';

const apiKey = import.meta.env.VITE_NEXUS_API_KEY;
assertPublicKey(apiKey);  // narrows to PublicApiKey

<NexusProvider config={{ baseUrl: '...', apiKey }}>
```

## Where to keep the API key

Anywhere your existing build pipeline injects environment-specific config - typically `.env` files for Vite / CRA, or `NEXT_PUBLIC_*` variables for Next.js. `wxp_...` keys are intended to be public, so embedding them in the built JavaScript bundle is fine.

<CodeGroup>
  ```tsx title="Vite" theme={null}
  <NexusProvider config={{
    baseUrl: import.meta.env.VITE_NEXUS_URL,
    apiKey:  import.meta.env.VITE_NEXUS_API_KEY,
  }}>
  ```

  ```tsx title="Next.js" theme={null}
  <NexusProvider config={{
    baseUrl: process.env.NEXT_PUBLIC_NEXUS_URL!,
    apiKey:  process.env.NEXT_PUBLIC_NEXUS_API_KEY!,
  }}>
  ```
</CodeGroup>

## Choosing the TTL

The TTL is a tradeoff between staleness window and redundant network traffic. With SSE enabled (the default), **changes propagate in milliseconds regardless of the TTL** - the TTL only matters as a safety net when the stream falls back.

| Use case                                     | Suggested `ttlMs` |
| -------------------------------------------- | ----------------- |
| Frequently-changing flags, latency-sensitive | 30 000 (30 s)     |
| Standard configs with SSE                    | 60 000 (default)  |
| Boot-time only, rarely re-checked            | 600 000 (10 min)  |
