Deploy to Netlify
Deploy Frontend and Backend to Netlify
Use two Netlify sites from the same repo: one for the Next.js frontend, one for the Express API (serverless function).
Overview
| Site | Base directory | Build | Result |
|------|----------------|--------|--------|
| Frontend | frontend | Next.js (npm run build) | App at https://YOUR-FRONTEND-SITE.netlify.app |
| Backend | backend | Prisma + TypeScript → Netlify Function | API at https://YOUR-BACKEND-SITE.netlify.app |
The frontend must know the backend URL via NEXT_PUBLIC_API_URL. Set it on the frontend site after the backend is deployed.
1. Deploy the backend (API) first
- In Netlify: Add new site → Import an existing project.
- Connect the uniph.ai repo.
- Build settings:
- Base directory:
backend - Build command: (leave default; uses
backend/netlify.toml:npx prisma generate && npm run build) - Publish directory: leave empty (this site only serves the function)
- Base directory:
- Environment variables (Site settings → Environment variables):
- Run migrations against that database once (e.g. locally):
Or usecd backend && DATABASE_URL="postgresql://..." npx prisma migrate deploynpx prisma db pushif you're not using migrations yet. - Deploy. Note the backend site URL, e.g. https://uniph-api.netlify.app (no trailing slash).
Check: Open https://YOUR-BACKEND-SITE.netlify.app/api/health. You should see {"ok":true,"db_configured":true,...}. If db_configured is false, set DATABASE_URL on the backend site and redeploy.
2. Deploy the frontend
- In Netlify: Add new site → Import an existing project (same repo).
- Build settings:
- Base directory:
frontend - Build command: (default from
frontend/netlify.toml:npm run build) - Publish directory: (default; Next.js plugin uses
.next)
- Base directory:
- Environment variables (Site settings → Environment variables):
- NEXT_PUBLIC_API_URL =
https://YOUR-BACKEND-SITE.netlify.app(the backend URL from step 1; no trailing slash). - AUTH_SECRET = a random secret (e.g.
openssl rand -base64 32). - NEXTAUTH_URL =
https://YOUR-FRONTEND-SITE.netlify.app(this site's URL; set after first deploy or use a custom domain). - For OAuth: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET and/or MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET (and in the OAuth provider console, add this site's URL as redirect/callback).
- NEXT_PUBLIC_API_URL =
- Deploy. After the first deploy, set NEXTAUTH_URL to the real site URL if you didn't already, then trigger a new deploy so it's baked in.
Check: Open the frontend URL, go to /auth, and sign in. Then open the dashboard; it should call the backend and show data (or empty state if no data yet).
3. Summary checklist
| Where | Variable | Value |
|-------|----------|--------|
| Backend site | DATABASE_URL | Production Postgres URL |
| Frontend site | NEXT_PUBLIC_API_URL | Backend Netlify URL (e.g. https://uniph-api.netlify.app) |
| Frontend site | AUTH_SECRET | Random secret |
| Frontend site | NEXTAUTH_URL | Frontend Netlify URL (e.g. https://uniph.netlify.app) |
| Frontend site (optional) | GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | For Google sign-in |
| Frontend site (optional) | MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET | For Microsoft sign-in |
4. Troubleshooting
-
Frontend shows "Unable to connect to the API"
SetNEXT_PUBLIC_API_URLon the frontend site to the backend URL, then trigger a new deploy (build-time variable). -
Backend
/api/healthshowsdb_configured: false
SetDATABASE_URLon the backend site and redeploy. -
Auth redirect or 500
EnsureNEXTAUTH_URLmatches the frontend URL (or custom domain) and that the OAuth app (Google/Microsoft) has the correct callback URL (e.g.https://YOUR-FRONTEND-SITE.netlify.app/api/auth/callback/google). -
Build fails
- Frontend: ensure Base directory is
frontendand Node 20 (seefrontend/netlify.toml). - Backend: ensure Base directory is
backend; check build log for Prisma/TS errors.
- Frontend: ensure Base directory is
5. Post-deploy smoke check (release gates)
From the repo root you can run a health check against the deployed backend (e.g. in CI or after deploy):
BACKEND_URL=https://YOUR-BACKEND-SITE.netlify.app npm run pre-deploy-check
To require that the database is configured (fail if db_configured is false):
BACKEND_URL=https://... REQUIRE_DB=1 npm run pre-deploy-check
See scripts/pre-deploy-check.mjs and roadmap Phase C (Release Reliability Gates).
To run the same check in CI: add BACKEND_URL to repo Secrets, then run the Smoke check (backend) workflow from the Actions tab (see .github/workflows/smoke-check.yml). For rollback steps, see Rollback playbook.
More detail:
- Backend:
backend/DEPLOY_NETLIFY.mdandbackend/docs/NETLIFY_TROUBLESHOOTING.md - Frontend:
frontend/DEPLOYMENT.mdand this app's Netlify Troubleshooting doc.