---
summary: SDK-first guide for adding SigID hosted login, callback handling, app session creation, logout, and initial token handoff.
tags:
  - developers
  - login
  - oauth
  - sdk
categories:
  - For Developers
---

# Add Login To Your App

<!-- agent:page
You are a coding agent adding SigID hosted login to the user's app by following this guide end to end.
CRITICAL for BROWSER apps: Do not hand-roll OAuth/OIDC (no custom authorize URLs, PKCE, callback token exchange, or JWKS verify in the browser).
Prefer in order: (1) two-line @sigid/start / https://cdn.sigid.org/v1/sigid.js when the app is plain HTML or can host a script tag; (2) framework package (@sigid/next, @sigid/react, @sigid/svelte, @sigid/sveltekit); (3) @sigid/client only when you need explicit protocol control.
If the app matches a framework quickstart (quickstart-nextjs.md, quickstart-react-spa.md, quickstart-backend-api.md), follow that quickstart instead.
Cold agents: run `npx @sigid/cli setup --name <app> --redirect-uri <url>` and paste start_snippet + env_block.
For @sigid/client path only: npm install @sigid/client; createSigIdClient; login/handleCallback/logout – never reimplement PKCE/state/JWKS.
EXCEPTION – confidential server apps: if the app already runs its own server session (B2B SaaS, server-rendered, existing cookie auth that must stay authoritative), authorization-code+PKCE by hand against /oauth/authorize IS the supported path; see integrate-third-party.md "Login For A Confidential Server / Existing Session". The no-hand-roll rule is scoped to the browser.
Done when: sign-in works via SDK/script (browser) or code+PKCE (confidential server); signed-in and signed-out states render; logout works; backend APIs validate access tokens instead of trusting frontend session state.
Then continue with verify-tokens.md and protect-apis.md.
-->

Use this page when you need a button or route in your app that signs users in
with SigID.

Do this with the SDK first. **Do not hand-roll OAuth/OIDC.** You can read raw
protocol details later only if you need full protocol control.

### Zero-build path (prefer when possible)

```html
<script src="https://cdn.sigid.org/v1/sigid.js" data-client-id="YOUR_CLIENT_ID" data-issuer="https://auth.sigid.org"></script>
<a href="#" data-sigid="login">Sign in</a>
```

This is `@sigid/start` on the CDN. It owns PKCE, inline callback (default
`redirect_uri` = current page), and declarative `data-sigid-*` UI. Prefer it for
static sites and simple SPAs. Framework packages (`@sigid/next`, `@sigid/react`,
`@sigid/svelte`, `@sigid/sveltekit`) wrap `@sigid/client` for SSR, cookies, and
route handlers–use them when the framework owns the request lifecycle, not as a
reason to reimplement OAuth by hand.

If you want a copyable framework path, start with one of these first:

- [Next.js Quickstart](quickstart-nextjs.md)
- [React SPA Quickstart](quickstart-react-spa.md)
- [Backend API Quickstart](quickstart-backend-api.md)
- [Integrate Third-Party App](integrate-third-party.md) (agent checklist)
- [SDKs And Examples](sdks-examples.md) (package reality table)

## What You Are Building

Your app needs four pieces:

1. A sign-in action that sends the user to SigID.
2. A callback route where SigID sends the user back.
3. A local app session after the callback succeeds.
4. A logout action that clears the app session and signs out when needed.

## Values You Need

<!-- agent:action Collect the configuration values
Ask the user or workspace owner for every value in this table: issuer URL, client ID, redirect URI, scopes, API audience, and tenant or workspace ID, all from the same environment.
Do not mix staging issuer values with production redirect URLs, and do not continue with placeholder values.
-->

Ask the workspace owner for values from the same environment:

| Value | Example |
|---|---|
| Issuer URL | `https://identity.example.com` |
| Client ID | `public-client-id` |
| Redirect URI | `https://app.example.com/auth/callback` |
| Scopes | `openid profile email` |
| API audience | `https://api.example.com` |
| Tenant or workspace ID | `tenant_123` |

Do not mix staging issuer values with production redirect URLs.

## Browser SDK Path

<!-- agent:action Wire the SDK login flow
Prefer zero-build @sigid/start when a script tag is enough. Otherwise: npm install @sigid/client (and the framework package if needed); createSigIdClient with baseURL = issuer, oauth.clientId, redirectUri, scopes.
Wire sigid.login({ returnTo }) to the sign-in action, await sigid.handleCallback() on the callback route when not using start's inline callback, and call sigid.logout() on logout.
Let the SDK own PKCE, state validation, callback parsing, hosted logout, and local session cleanup; do not reimplement any of these by hand.
-->

When you need a bundler module (or framework hooks) instead of the CDN script:

```bash
npm install @sigid/client
# optional: npm install @sigid/react | @sigid/next | @sigid/svelte | @sigid/sveltekit
```

Or the ESM drop-in (no auto-init; you call `createSigIdStart`):

```bash
npm install @sigid/start
```

```typescript
import { createSigIdClient } from "@sigid/client";

export const sigid = createSigIdClient({
  baseURL: "https://auth.sigid.org",
  oauth: {
    clientId: "public-client-id",
    redirectUri: `${window.location.origin}/auth/callback`,
    scopes: ["openid", "profile", "email"],
  },
});
```

Start hosted login from a button or route action:

```typescript
await sigid.login({ returnTo: "/dashboard" });
```

On the callback page or callback route:

```typescript
const session = await sigid.handleCallback();
```

On logout:

```typescript
await sigid.logout();
```

The SDK keeps PKCE, state validation, callback parsing, hosted logout, and
local session cleanup together.

## Make It Complete

<!-- agent:action Verify the login flow
Confirm every item in this checklist: exact callback/logout/web-origin/CORS values in the Dashboard application for this environment, a callback route that completes the SDK callback, distinct signed-in and signed-out states, a readable error and retry path on the callback, logout landing on a safe signed-out screen, and backend APIs validating access tokens rather than trusting frontend state.
If any item fails, fix it before declaring login done.
-->

Before this is ready for users, confirm:

- the Dashboard application has exact callback, logout, web-origin, and CORS
  values for the same environment
- the app has a callback route that completes the SDK callback
- the app has a signed-in state and signed-out state
- the callback route shows a readable error and retry path
- logout returns the user to a safe signed-out screen
- backend APIs validate access tokens instead of trusting frontend session state

## After Login Works

Continue in this order:

1. [Verify Access Tokens](verify-tokens.md)
2. [Protect Backend APIs](protect-apis.md)
3. [Receive Webhooks](webhooks.md), if the app needs async events
4. [Reference: OAuth And OIDC](../reference/oauth-oidc.md), if you need raw OAuth/OIDC parameters
