Visitor auth for static apps: protect demos without a full backend

If you searched for visitor auth for static apps, you probably need login on a static app without standing up a Node server, configuring OAuth, or paying for a full auth platform. jsdeck's secure accounts (auth API) — also called visitor auth — gives each hosted app its own email/password accounts, session tokens, and optional per-user datastore rows. This guide explains how it works, shows real API calls, and is honest about when to use Clerk, Auth0, or a full backend instead.
Why static apps need a different auth model
Traditional auth tutorials assume you control a server: set cookies, run middleware, store sessions in Redis. A jsdeck-hosted app is static files on HTTPS — HTML, CSS, and JS. The auth API is a hosted REST layer your frontend calls directly, the same way you might call the datastore. No express-session, no Lambdas to deploy.
What secure accounts (auth API) is
jsdeck's auth API creates per-app secure accounts for visitors to your hosted app at https://your-slug.jsdeck.com. Each account is an email + password scoped to that app slug only. After register or login the API returns an accessToken — a bearer session token (default 7 days, server-side).
This is not your jsdeck dashboard login. Dashboard accounts deploy and configure apps; secure accounts sign into *your* demo or product UI. Full route reference: Secure accounts (auth API) docs.
Auth HTTP routes (summary)
All calls use the apex base https://jsdeck.com/api/v1 (CORS allows *.jsdeck.com). Replace {slug} with your app name:
| Method | Path | Purpose |
|---|---|---|
| POST | /public/apps/{slug}/users/register | Create account (email, password min 8 chars) |
| POST | /public/apps/{slug}/users/login | Sign in — returns accessToken, expiresAt, user |
| GET | /public/apps/{slug}/users/me | Current user — Authorization: Bearer <session token> |
| POST | /public/apps/{slug}/users/logout | Revoke session |
| POST | /public/apps/{slug}/users/forgot-password | Send reset email |
| POST | /public/apps/{slug}/users/reset-password | Complete reset with token + newPassword |
OpenAPI spec: /tenant-auth-api.yaml.
Example: login from your static frontend
const API = 'https://jsdeck.com/api/v1';
const SLUG = 'your-app';
async function login(email, password) {
const res = await fetch(`${API}/public/apps/${SLUG}/users/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!res.ok) throw new Error('Invalid email or password');
const { accessToken, user } = await res.json();
sessionStorage.setItem('sessionToken', accessToken);
return user;
}
async function currentUser(token) {
const res = await fetch(`${API}/public/apps/${SLUG}/users/me`, {
headers: { Authorization: `Bearer ${token}` },
});
return res.ok ? (await res.json()).user : null;
}
Store the session token like a session cookie — HTTPS only, avoid logging it. The @jsdeck/toolkit package wraps register, login, and datastore calls with configure({ tenantUserToken }).
Gate a demo behind login (no backend code)
Your static bundle can show a login form until a valid session token exists:
// Pseudocode — adapt to React, Vue, Svelte, etc.
const token = sessionStorage.getItem('sessionToken');
async function boot() {
if (!token) {
renderLoginForm({ onSuccess: (t) => { sessionStorage.setItem('sessionToken', t); boot(); } });
return;
}
const user = await currentUser(token);
if (!user) {
sessionStorage.removeItem('sessionToken');
boot();
return;
}
renderYourApp(user); // demo visible only after auth
}
The hosted HTML is still public — you decide in client code what to render before login. For a client preview, create one shared demo account or register separate accounts per stakeholder.
Per-user private data (owner rows)
Auth pairs with the optional JSON datastore. After login, PUT records with visibility: "owner" so only that user's session token can read or write them — the shared store_ key cannot. Lists omit owner rows unless the request includes a valid session token. See owner-row docs for using the datastore key together with a session token.
Password reset
Call forgot-password with the user's email and optionally redirectPath (e.g. "/reset-password") so the reset link opens on your hosted app. Your reset page reads ?token= from the URL and POSTs to reset-password with newPassword. Use reset-password/status?token= to show "link expired" before asking for a new password.
Limits and when auth API is not enough
jsdeck auth fits email/password per app, gated demos, and owner-scoped JSON rows. It does not include social/OAuth login, MFA, SAML/SSO, org roles, audit logs, or compliance certifications. Apps are capped at 5,000 secure accounts per app — plenty for demos and small products. Need Google sign-in, enterprise SSO, or fine-grained RBAC? Use Clerk, Auth0, or Supabase Auth and keep jsdeck for static hosting only. See what the auth API covers for scope details.
Enable and ship
- Deploy your static build to jsdeck
- Enable the datastore in the dashboard if you need saved or per-user data
- Add a login/register UI that calls the auth API routes above
- Gate your main UI until
GET /users/mesucceeds - Read the full auth API guide for reset flows and toolkit helpers
Who this is for, and when not to use jsdeck auth
Good fit: gated demos, client previews, hackathon apps, MVPs, and per-user JSON via owner rows.
Not a fit: OAuth-only login, MFA requirements, enterprise SSO, complex roles, or regulated identity workloads — use Clerk, Auth0, or Supabase Auth instead.
Frequently asked questions
Is visitor auth for static apps really free?
Yes. jsdeck offers free static hosting with HTTPS. Secure accounts (auth API) and the optional datastore are included for typical demo and side-project scale — no credit card to start.
Is secure accounts the same as my jsdeck dashboard login?
No. Your dashboard account deploys apps on jsdeck.com. Secure accounts are end-users signing into *your* app at your-slug.jsdeck.com via the auth API.
Can visitors sign in with Google or GitHub?
Not today — email and password only. For social login or SSO, use a dedicated identity provider. See what jsdeck auth covers and the comparisons hub for when another platform fits better.
Next steps
- Explore more guides in the visitor auth hub
- Follow the getting started guide to deploy your first app
- Read Secure accounts (auth API) for full route docs and OpenAPI