Skip to main content
Both platforms share the same Trace account system as the main app (same Supabase project, same JWT). A token minted anywhere in the Trace ecosystem works on either site.

Token storage

src/lib/auth.ts keeps tokens in localStorage:
BACKEND_URL resolves to process.env.NEXT_PUBLIC_BACKEND_URL || "https://api.buildwithtrace.com".

Email + password login

The login page POSTs directly to the backend, then stores the returned tokens:

GitHub OAuth

handleGitHubLogin() redirects to the backend, passing a callback that tells it which site to return to:
The footprints site sends callback=footprints. The backend must have that callback registered for footprints.buildwithtrace.com or GitHub OAuth will fail there. Email/password login works regardless.

Authenticated requests & auto-refresh

fetchWithAuth(url, options) attaches the bearer token and, on a 401, transparently refreshes via POST /api/v1/auth/refresh and retries once:
Refresh flow:
If refresh fails, clearTokens() is called and the user is signed out.

Which endpoints require auth

GET
Browse, search, semantic search, suggestions, library detail, categories, thumbnails, download, community list, comment reads, rating reads, health.
POST / PATCH / DELETE
Generate, generate/save, contribute/submit, my-symbols / my-footprints (GET/PATCH/DELETE), posting comments, posting ratings.

Plan gating

Generation is plan-restricted on the backend. Proxy routes surface this directly: The site renders an “Upgrade required” state on 402/403 and links to pricing.