Static deploy
The generated app is a Vite project. Publishing is the usual static flow: you produce a dist/ folder and serve it from any static file host — no server, no lock-in.
Build it
npm run build
Typical output:
vite v5.4.21 building for production... ✓ 34 modules transformed. dist/index.html 0.40 kB │ gzip: 0.27 kB dist/assets/index-...css 0.00 kB │ gzip: 0.02 kB dist/assets/index-...js 143.00 kB │ gzip: 46.00 kB ✓ built in 274ms
The result is a dist/ folder with an index.html and the assets in dist/assets/. To check it locally before shipping:
npm run preview
The rule every host needs: rewrite to index.html
The app is a SPA (single-page app): every route is served by index.html and routing happens in the browser. That's why every host needs a rewrite rule sending any path to index.html — otherwise a refresh on /crm returns a 404.
Vercel — create a vercel.json at the root:
{ "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] }
Build command: npm run build · Output directory: dist.
Netlify — create a public/_redirects:
/* /index.html 200
Build command: npm run build · Publish directory: dist.
Cloudflare Pages — same _redirects as Netlify:
/* /index.html 200
Build command: npm run build · Output directory: dist.
Environment variables
In your host's dashboard, set the public variables — the same ones from your .env.local:
VITE_SUPABASE_URL=https://YOUR-REF.supabase.co VITE_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_PAT does not go to the host. It's only for fayz db apply, which you run from your own machine. Only the VITE_ values (public, embedded in the browser) belong on the host. Never put the PAT in a deploy build variable.
Point the project at your repository, configure build + output per the host above, set the variables and deploy. The same dist/ runs identically on all three.
Next: the managed deploy that's on its way, in Fayz deploy.