@sigid/start
v0.1.0
Published
Drop-in browser script for SigID authentication. Add hosted OAuth login in two lines, no build step.
Maintainers
Readme
@sigid/start
Drop-in browser script for SigID authentication. Add hosted OAuth (PKCE) login in two lines – no build step, no framework, no callback page.
<script src="https://cdn.sigid.org/v1/sigid.js" data-client-id="app_abc123" data-issuer="https://auth.sigid.org"></script>
<a href="#" data-sigid="login">Sign in</a>That is the whole integration. The dashboard's "Create app" screen and
npx @sigid/cli setup print this snippet with your client_id already filled
in. Coding agents must paste it rather than hand-rolling OAuth/OIDC.
Canonical CDN: https://cdn.sigid.org/v1/sigid.js (also mirrored on
https://www.sigid.org/v1/sigid.js). npm package @sigid/start for bundlers.
Package entry vs CDN
| Import | Behavior |
| --- | --- |
| import { createSigIdStart } from "@sigid/start" | Side-effect free. Safe for bundlers and frameworks. |
| CDN sigid.js / dist/index.global.js | Auto-inits from the loading <script data-client-id> tag. |
Publishing
Independent of cluster deploy:
# Cloudflare Pages → https://cdn.sigid.org/v1/sigid.js
just publish-start-sdk --cdn
# npm: @sigid/client then @sigid/start
just publish-start-sdk --npm
just publish-start-sdk --all # both
just publish-start-sdk --cdn --dry-runSee scripts/runbook/publish/README.md and DEPLOYMENT.md § Off-cluster publish.
import { createSigIdStart } from "@sigid/start";
const sigid = createSigIdStart({
config: { clientId: "app_abc123", issuer: "https://auth.acme.com" },
});
await sigid.ready;Pass bindDom: false when a framework owns the UI and you only need the
imperative API / events.
What the script does for you
- Hosted OAuth + PKCE, entirely inside the script. The browser only ever
holds the public
client_id– there is no secret in this snippet. PKCE replaces it. - Inline callback.
redirect_uridefaults to the current page, so when the user returns the script completes the code exchange in place, firessigid:signin, and scrubs?code&statefrom the URL. You do not write a callback route. - Declarative UI. Mark up signed-in / signed-out blocks and user fields and the script keeps them in sync.
Declarative attributes
<script src="https://cdn.sigid.org/v1/sigid.js" data-client-id="app_abc123" data-issuer="https://auth.sigid.org"></script>
<div data-sigid-loading hidden>Checking session…</div>
<div data-sigid-error hidden></div>
<div data-sigid-signed-out>
<a href="#" data-sigid="login">Sign in</a>
<a href="#" data-sigid="signup">Create account</a>
<a href="#" data-sigid="login" data-prompt="login">Sign in only</a>
</div>
<div data-sigid-signed-in hidden>
<img data-sigid-user="picture" alt="" />
Hi, <span data-sigid-user="name"></span>
<a href="#" data-sigid="logout">Sign out</a>
</div>| Attribute | Effect |
| --- | --- |
| data-sigid="login" | Clicking starts hosted login |
| data-sigid="signup" | Clicking starts hosted signup (prompt=create) |
| data-sigid="logout" | Clicking starts hosted logout |
| data-prompt | Per-control OIDC prompt override (login, create, …) |
| data-return-to | App path restored after the OAuth callback |
| data-sigid-signed-in | Shown only when authenticated |
| data-sigid-signed-out | Shown only when not authenticated |
| data-sigid-loading | Shown until the first session/callback probe finishes |
| data-sigid-error | Shown when auth fails; filled with the error message |
| data-sigid-user="name" | Filled with display name (falls back to email) |
| data-sigid-user="email" | Filled with email |
| data-sigid-user="id" | Filled with the user id |
| data-sigid-user="picture" | Sets src on an <img> |
Add hidden to the signed-in (and loading/error) blocks to avoid a flash before
the session check resolves.
Script configuration
Configuration is read from data-* attributes on the <script> tag.
| Attribute | Default | Notes |
| --- | --- | --- |
| data-client-id | – | Required. Public client id from the dashboard |
| data-issuer | https://sigid.org | Override for self-hosting or a tenant subdomain |
| data-scopes | openid profile email | Space- or comma-separated |
| data-redirect-uri | current page | Must be on the app's registered redirect-URI allowlist |
| data-dpop | off | true to bind tokens with DPoP |
| data-base-path | /api/v1/identity | Identity API base path |
The registered redirect-URI allowlist still applies. By default the page that hosts the snippet is the redirect target, so register that URL (the dashboard captures it for you). This allowlist is the security boundary the snippet keeps that origin-derived "zero-registration" auth scripts throw away.
Imperative API
After load, window.sigid is the live instance (CDN path):
await window.sigid.ready; // resolves with the session (or null)
window.sigid.getUser(); // { id, email, name, image_url } | null
window.sigid.login({ returnTo, prompt });
window.sigid.logout();
window.sigid.isReady();
window.sigid.getError();
window.sigid.on("change", (s) => console.log("session", s));
window.sigid.on("error", (e) => console.error(e));Window events: sigid:ready, sigid:signin, sigid:signout, sigid:change,
and sigid:error.
When to reach for more
This package is the zero-build tier. For framework apps with their own bundler,
use @sigid/react, @sigid/next, @sigid/svelte, or @sigid/sveltekit. For
full protocol control (explicit callback routes, custom storage), use
@sigid/client directly. All of them share the same @sigid/client engine.
License
MIT
