---
summary: Run the SigID Next.js SDK Lab example locally, configure environment values, verify visible states, and understand what the local gate does and does not prove.
tags:
  - developers
  - examples
  - nextjs
  - sdk-lab
categories:
  - For Developers
---

# Run The Example App

<!-- agent:page
You are a coding agent running the SigID SDK Lab example at examples/sdk-lab-next so the user can see the golden TypeScript / Next.js path before wiring their own app.
For live hosted login, collect from the user or workspace admin: issuer URL, client ID, API audience, scope, and tenant ID for the target deployment. The registered application must use App URL http://localhost:3006, callback http://localhost:3006/auth/callback, a public PKCE client, and scopes openid profile email projects:read:sdk-lab.
Implementation order:
- create examples/sdk-lab-next/.env.local with NEXT_PUBLIC_SIGID_ISSUER_URL, NEXT_PUBLIC_SIGID_CLIENT_ID, NEXT_PUBLIC_APP_URL=http://localhost:3006, NEXT_PUBLIC_SIGID_SCOPES, SIGID_API_AUDIENCE, SIGID_API_SCOPE, SIGID_TENANT_ID
- from examples/sdk-lab-next run: bun install --frozen-lockfile, then bun run dev, then open http://localhost:3006
- with the dev server running, run the gate from the repository root: SDK_LAB_NEXT_BASE_URL=http://localhost:3006 bunx playwright test tests/playwright/sdk-lab-next/quality-gate.spec.ts
Success: the page shows heading "SigID Next.js SDK Lab", state "Signed out", a "Start hosted login" button, and the configured issuer, client ID, redirect URI, and scopes; the gate passes. The gate proves local UI wiring and fail-closed API behavior, not live hosted login.
Common failures: callback fails when the registered callback URL is not exactly http://localhost:3006/auth/callback; wrong_audience or wrong_tenant from the protected API means SIGID_API_AUDIENCE or SIGID_TENANT_ID does not match the token.
-->

Use this guide when you want to see the SigID SDK path in a working local
Next.js app before wiring your own application.

The example lives at `examples/sdk-lab-next`. It is an integration lab for the
current TypeScript / Next.js golden path.

## What The Example Shows

- `@sigid/client` browser configuration
- `@sigid/react` provider, sign-in, callback, session, protected UI, and logout
- `@sigid/next` auth route handlers
- `requireAccessToken()` on a protected API route
- readable errors for callback, redirect, audience, and scope problems
- local negative-path tests that do not require a live SigID tenant

## Configure A SigID Application

<!-- agent:action Register the application
Have the user or workspace admin register an application with exactly this table's values: App URL http://localhost:3006, Allowed Callback URL http://localhost:3006/auth/callback, matching logout/web-origin/CORS values, a public PKCE client, scopes openid profile email projects:read:sdk-lab, and the API audience.
This step is only required for live hosted login; the local UI and the quality gate work without it.
-->

For live hosted login, register this application configuration:

| Field | Value |
|---|---|
| App URL | `http://localhost:3006` |
| Allowed Callback URL | `http://localhost:3006/auth/callback` |
| Allowed Logout URL | `http://localhost:3006` |
| Allowed Web Origin | `http://localhost:3006` |
| Allowed Origins (CORS) | `http://localhost:3006` |
| Client type | Public PKCE client |
| Scopes | `openid profile email projects:read:sdk-lab` |
| API audience | `https://api.example.local/projects` |

## Provision The Local Live-Proof Seed

For live hosted login against the **local** container stack, you can
self-provision the application seed instead of asking a workspace admin. With
the dev stack up (`just dev`), run from the repository root:

```bash
just sdk-lab-provision
```

This ensures the `demo` tenant and the `sigid-sdk-lab-next` public PKCE app
exist in the local development Postgres (via the `sigid_privileged` bootstrap
functions) with the exact client ID, audience, callback, and scopes above. It
is a dev-only seed, not a production provisioning path. To check readiness
without writing anything, run `just sdk-lab-readiness`, which also prints the
non-secret `.env.local` values to copy into the next step.

## Create Environment Values

<!-- agent:action Create environment values
Create examples/sdk-lab-next/.env.local with NEXT_PUBLIC_SIGID_ISSUER_URL, NEXT_PUBLIC_SIGID_CLIENT_ID, NEXT_PUBLIC_APP_URL=http://localhost:3006, NEXT_PUBLIC_SIGID_SCOPES, SIGID_API_AUDIENCE, SIGID_API_SCOPE, and SIGID_TENANT_ID.
Replace the issuer, client ID, audience, scope, and tenant with values from the user's target deployment; the localhost defaults only suit the local stack.
-->

From `examples/sdk-lab-next`, create `.env.local`:

```bash
NEXT_PUBLIC_SIGID_ISSUER_URL=http://auth.sigid.localhost:3000
NEXT_PUBLIC_SIGID_CLIENT_ID=sigid-sdk-lab-next
NEXT_PUBLIC_APP_URL=http://localhost:3006
NEXT_PUBLIC_SIGID_SCOPES="openid profile email projects:read:sdk-lab"

SIGID_API_AUDIENCE=https://api.example.local/projects
SIGID_API_SCOPE=projects:read:sdk-lab
SIGID_TENANT_ID=tenant-id-required
```

Replace the issuer, client ID, audience, scope, and tenant with values from your
target deployment.

## Run

<!-- agent:action Run the example
From the repository root run: cd examples/sdk-lab-next && bun install --frozen-lockfile && bun run dev
Open http://localhost:3006 and confirm the page shows the "SigID Next.js SDK Lab" heading, the "Signed out" state, the "Start hosted login" button, and the configured issuer, client ID, redirect URI, and scopes.
If the app cannot start, make sure you are inside examples/sdk-lab-next and that workspace dependencies stay on workspace:*.
-->

From the repository root:

```bash
cd examples/sdk-lab-next
bun install --frozen-lockfile
bun run dev
```

Open:

```text
http://localhost:3006
```

## What Success Looks Like

Before live login, the local app should show:

- heading: `SigID Next.js SDK Lab`
- state: `Signed out`
- button: `Start hosted login`
- configured issuer, client ID, redirect URI, and scopes
- link to the protected page

After live login with a real tenant, you should be able to:

1. Start hosted login.
2. Complete the SigID prompt.
3. Return to `/auth/callback`.
4. See signed-in user/session metadata without raw tokens.
5. Open `/protected`.
6. Call the local protected API.
7. Sign out.

## Run The Local Gate

<!-- agent:action Run the quality gate
With the dev server still running, run from the repository root:
SDK_LAB_NEXT_BASE_URL=http://localhost:3006 bunx playwright test tests/playwright/sdk-lab-next/quality-gate.spec.ts
A passing gate proves local UI wiring and fail-closed API behavior for missing or malformed authorization; it does not prove live hosted login or token exchange, which need a real tenant and registered redirect URI.
-->

With the dev server running, run this from the repository root:

```bash
SDK_LAB_NEXT_BASE_URL=http://localhost:3006 \
  bunx playwright test tests/playwright/sdk-lab-next/quality-gate.spec.ts
```

The gate proves local UI wiring and fail-closed API behavior for missing or
malformed authorization. It does not prove live hosted login or successful token
exchange; those require a real tenant and registered redirect URI.

## If It Fails

| Symptom | Check |
|---|---|
| App cannot start | Run from `examples/sdk-lab-next` and keep workspace dependencies on `workspace:*`. |
| Button redirects to the wrong issuer | `NEXT_PUBLIC_SIGID_ISSUER_URL` is from the wrong environment. |
| Callback fails | The registered callback URL must be exactly `http://localhost:3006/auth/callback`. |
| Protected API returns `missing_bearer_token` | You are signed out or the frontend did not send a bearer token. |
| Protected API returns `wrong_audience` | `SIGID_API_AUDIENCE` does not match the token audience. |
| Protected API returns `wrong_tenant` | `SIGID_TENANT_ID` does not match the token tenant. |

After the example works, copy the same sequence into your app with
[Next.js Quickstart](quickstart-nextjs.md).
