Build with React
A browser SPA should hold only the publishable pieces: the auth client and your API’s URL. Postgres, storage keys, and cache stay behind your Node API (or any backend).
Auth in the browser
Section titled “Auth in the browser”npm install @supabase/supabase-jsimport { createClient } from '@supabase/supabase-js';export const auth = createClient(import.meta.env.VITE_AUTH_URL, import.meta.env.VITE_AUTH_ANON_KEY);
// Sign in, then call your API with the session tokenconst { data } = await auth.auth.signInWithPassword({ email, password });await fetch('/api/todos', { headers: { Authorization: `Bearer ${data.session.access_token}` } });Uploads without exposing keys
Section titled “Uploads without exposing keys”Have your backend mint signed upload URLs so the browser PUTs directly to storage — no S3 credentials in the client.
Realtime
Section titled “Realtime”const ws = new WebSocket(`wss://…/connection/websocket?token=${connToken}`);Your backend mints short-lived connection tokens — see Realtime.
Host it on Impulse
Section titled “Host it on Impulse”vite build, then serve dist/ from an ImpulseDrive bucket with static hosting or any web hosting plan. Point the SPA at your API’s domain.