> For the complete documentation index, see [llms.txt](https://docs.kydlabs.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kydlabs.com/sdks/browser-sdk.md).

# Javascript Browser

The KYD Labs Browser SDK wraps the browser side of the OIDC authorization flow. It handles PKCE generation, authorize redirects, callback code exchange, userinfo lookup, session storage, refresh tokens, and authenticated API requests.

## Install

```bash
npm install @kydlabs/browser-sdk
```

## Create A Client

```ts
import { KYDLabsBrowserSDK } from "@kydlabs/browser-sdk";

const kyd = new KYDLabsBrowserSDK({
  clientId: "your_client_id",
  redirectUri: "https://app.example.com/callback",
});
```

## Constructor Options

```ts
type KYDLabsBrowserSDKOptions = {
  issuer?: string;
  clientId: string;
  redirectUri: string;
  storageKeyPrefix?: string;
  defaultOidcScope?: string;
};
```

| Option             | Description                                                                                                                                     |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `issuer`           | Optional OIDC issuer. Defaults to `https://auth.kydlabs.com`.                                                                                   |
| `clientId`         | Required OIDC client ID.                                                                                                                        |
| `redirectUri`      | Required callback URL registered on the OIDC client.                                                                                            |
| `storageKeyPrefix` | Optional prefix for `sessionStorage` keys. Defaults to `kydlabs`.                                                                               |
| `defaultOidcScope` | Optional scope string used by `login()` and `loginWithPopup()`. Defaults to `openid profile offline_access fan:tickets:read fan:tickets:write`. |

## Return Types

```ts
type OidcUserInfo = {
  sub: string;
  scope: string;
  iss: string;
  aud: string;
};

type KYDLabsSession = {
  accessToken: string;
  idToken: string;
  refreshToken?: string;
  expiresAt: number;
  userInfo: OidcUserInfo;
};
```

`expiresAt` is a Unix timestamp in milliseconds.

## `login()`

```ts
await kyd.login();
```

Starts a full-page OIDC login. The SDK:

* generates PKCE `code_verifier` and `code_challenge`
* generates `state`
* stores the authorize request in `sessionStorage`
* redirects the current page to `/oauth2/authorize`

Use this when replacing the current page with the KYD hosted login is acceptable.

## `loginWithPopup()`

```ts
const result = await kyd.loginWithPopup();
```

Starts OIDC login in a popup window and resolves with `KYDLabsSession` after the callback completes.

The SDK opens the authorize URL in a popup and waits up to 120 seconds for a callback message. Your callback page must detect that it is running in a popup and send the callback query string back to the opener:

```ts
if (window.opener && window.opener !== window) {
  window.opener.postMessage(
    {
      type: "kydlabs:oidc:callback",
      search: window.location.search,
    },
    "*"
  );
  window.close();
}
```

The SDK accepts the message only when it comes from the popup and from either the current app origin or the registered redirect URI origin.

## `exchangeCode()`

```ts
const result = await kyd.exchangeCode();
```

Completes a redirect-based login on your callback route. The SDK reads `code` and `state` from `window.location.search`, validates the stored `state`, exchanges the code at `/oauth2/token`, calls `/oauth2/userinfo`, stores the session, and returns `KYDLabsSession`.

Call this only on the callback page after `login()` redirected the user back to your app.

## `getSession()`

```ts
const session = kyd.getSession();
```

Returns the stored `KYDLabsSession` from `sessionStorage`, or `null` if no session is available. This method does not refresh expired access tokens.

Use `getAccessToken()` when you need a valid access token.

## `clearSession()`

```ts
kyd.clearSession();
```

Removes the stored KYD Labs session from `sessionStorage`. Use this for sign-out or when your app wants to force a fresh login.

## `getAccessToken()`

```ts
const accessToken = await kyd.getAccessToken();
```

Returns a valid access token for the current session.

If the stored access token is still valid, the SDK returns it. If the token is expired or close to expiry, the SDK uses the stored refresh token to refresh the session first. If there is no session, or the access token is expired and no refresh token is available, it throws.

## `authenticatedFetch()`

```ts
const response = await kyd.authenticatedFetch(
  "https://api.kydlabs.com/fans/tickets"
);
```

Wraps `fetch()` and adds:

```http
Authorization: Bearer <ACCESS_TOKEN>
```

It calls `getAccessToken()` first, so it can refresh the session before making the request.

The method accepts the same input shape as `fetch`:

```ts
await kyd.authenticatedFetch("https://api.kydlabs.com/fans/tickets", {
  method: "GET",
});
```

## `refreshSession()`

```ts
const session = await kyd.refreshSession();
```

Forces a refresh token exchange and stores the refreshed session.

This requires a stored session with a `refreshToken`. KYD returns refresh tokens only when `offline_access` was requested and the client is allowed to use refresh tokens.

## Typical Redirect Flow

```ts
const kyd = new KYDLabsBrowserSDK({
  clientId: "your_client_id",
  redirectUri: "https://app.example.com/callback",
});

await kyd.login();
```

On `https://app.example.com/callback`:

```ts
const result = await kyd.exchangeCode();
console.log(result.userInfo);
```

For API calls:

```ts
const tickets = await kyd
  .authenticatedFetch("https://api.kydlabs.com/fans/tickets")
  .then((response) => response.json());
```

## Typical Popup Flow

```ts
const result = await kyd.loginWithPopup();
console.log(result.accessToken);
```

The popup flow still requires a registered callback route. That route sends the `kydlabs:oidc:callback` message back to the opener window, and the opener performs the code exchange.
