Vercel
Deploy OpenQuok Application to Vercel — backend/web projects, env vars, CLI, and domains.
Deploy the backend (Express) and web (SvelteKit) to Vercel.
Prerequisites
- Vercel account
- Vercel CLI (optional — `npx vercel` is enough)
Backend on Vercel
Create a new Vercel project
and connect this repository.
Set Root Directory to backend
Configure the build
Do not run the Vercel build on your local backend folder
The build uses backend/vercel.json: tsup bundles backend/handler/index.ts to api/index.js, and all traffic is rewritten to that serverless function (same Express app as local, via createApp in backend/app.ts; listen() is skipped when VERCEL is set).
Do not run that buildCommand on your local backend/ folder: the post-build script deletes source files; it is only safe on Vercel’s ephemeral build machine (or a throwaway clone).
Set environment variables
Set Environment Variables in the Vercel project to match production (same names as backend/.env.production.local): NODE_ENV, Supabase keys, REDIS_* (prefix), FRONTEND_DOMAIN_URL, BACKEND_DOMAIN_URL, Stripe, OAuth, Sentry, email, etc.
Sensitive environment options
CORS and production origins
- Set FRONTEND_DOMAIN_URL without a trailing slash (for example https://www.openquok.com, not https://www.openquok.com/).
- Include both apex and
wwwin ALLOWED_FRONTEND_ORIGINS (example: https://openquok.com,https://www.openquok.com). - Keep the web app’s VITE_API_BASE_URL pointing to the same backend origin used by BACKEND_DOMAIN_URL.
If these do not match, browser preflight for auth endpoints (such as /api/v1/auth/refresh) can fail with a CORS error.
Deploy
Deploy from the dashboard (push to the production branch) or from the repository root:
Deploy backend to Vercel (preview) — invokes the Vercel CLI with backend/ as the working directory.
pnpm vercel:deploy:backend Deploy backend to Vercel (production) — same command shape, production target.
pnpm vercel:deploy:backend:prod After deploy, set BACKEND_DOMAIN_URL to your backend URL (for example https://your-api.vercel.app or a custom domain). Point Stripe webhooks and Google OAuth redirect URIs at that URL. Set the web app’s VITE_API_BASE_URL to the same backend base URL.
Example CLI prompts (your paths and names may differ):
? Set up and deploy "~/Projects/solo/openquok-monorepo/backend"? yes
? Which scope should contain your project? ratimon's projects
? Link to existing project? no
? What's your project's name? openquok-backend
? In which directory is your code located? ./
Local settings detected in vercel.json:
- Build Command: npx tsup && sh scripts/vercel-clean-after-build.sh
- Install Command: cd .. && pnpm install --frozen-lockfile
- Output Directory: public
> Auto-detected Project Settings for Express
? Want to modify these settings? no
? Do you want to change additional project settings? noWeb on Vercel
Create a second Vercel project
and connect the same repository.
Set Root Directory to web
Include monorepo files in the build
Enable Include source files outside of the Root Directory in the Build Step (Project → Settings → General → Root Directory) so the monorepo lockfile and workspace install work.
SvelteKit adapter and config
web/svelte.config.js uses @sveltejs/adapter-vercel when VERCEL is set (Vercel sets this during build); otherwise it uses adapter-auto for local development.Optional overrides are in web/vercel.json (installCommand runs pnpm install from the repository root; buildCommand runs pnpm run build).
Set environment variables
Set Environment Variables to match production (same as web/.env.production): VITE_API_BASE_URL (your deployed backend), VITE_FRONTEND_DOMAIN_URL, VITE_PUBLIC_SUPABASE_* (prefix), Stripe and analytics keys as needed.
Deploy
Deploy web to Vercel (preview) — invokes the Vercel CLI with web/ as the working directory.
pnpm vercel:deploy:web Deploy web to Vercel (production) — same command shape, production target.
pnpm vercel:deploy:web:prodCustom domains (e.g. Route 53)
Add each domain in the Vercel project (Settings → Domains), create the DNS records Vercel shows (often CNAME to cname.vercel-dns.com or A records for apex), then set:
- Backend: BACKEND_DOMAIN_URL, FRONTEND_DOMAIN_URL (and ensure CORS allows the frontend origin).
- Web: VITE_API_BASE_URL, VITE_FRONTEND_DOMAIN_URL.