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

· jsdeck team · 5 min read
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:

MethodPathPurpose
POST/public/apps/{slug}/users/registerCreate account (email, password min 8 chars)
POST/public/apps/{slug}/users/loginSign in — returns accessToken, expiresAt, user
GET/public/apps/{slug}/users/meCurrent user — Authorization: Bearer <session token>
POST/public/apps/{slug}/users/logoutRevoke session
POST/public/apps/{slug}/users/forgot-passwordSend reset email
POST/public/apps/{slug}/users/reset-passwordComplete 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

  1. Deploy your static build to jsdeck
  2. Enable the datastore in the dashboard if you need saved or per-user data
  3. Add a login/register UI that calls the auth API routes above
  4. Gate your main UI until GET /users/me succeeds
  5. 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

About the author

The jsdeck team writes practical deployment guides for static JavaScript apps. Questions or corrections? Send feedback.

Ready to deploy?

Publish your static app to a live URL in minutes — free hosting with optional datastore and visitor auth.

Get started free