Status: Manual process — both Vercel and Render need to be linked by hand for each PR.
This documents the current (tedious) workflow. An automated solution is planned.
The AI Tutor is split across two hosting platforms:
| Service | Platform | Auto-deploys on PR? | URL pattern |
|---|---|---|---|
| Frontend | Vercel | Yes | ai-tutor-<hash>-array-education.vercel.app |
| Backend | Render (ai-tutor-api) |
Only when render-preview label is added |
ai-tutor-api-pr-<number>.onrender.com |
Vercel auto-deploys on every PR. Render only creates a Preview Environment
when you add the render-preview label to the PR. Once deployed, they
don't know about each other. The frontend needs the backend URL to make API
calls, and the backend needs the frontend URL for CORS. You have to wire them
together manually.
Push your branch and open a PR on GitHub.
- Vercel will start deploying automatically
- Render will not deploy until you add the
render-previewlabel to the PR
Add the label:
- On your PR page, click Labels in the right sidebar
- Select
render-preview - Render will pick this up and create a Preview Environment
Wait for both deploys to finish before proceeding.
Find it in one of these places:
- The Vercel bot comment on your PR (posted automatically)
- The deployment status check at the bottom of the PR → click "Details"
- The Vercel dashboard → Deployments tab → find your branch
It will look like: https://ai-tutor-<hash>-array-education.vercel.app
Go to the Render dashboard:
- Find the
ai-tutor-apiservice - Look for the Preview Environment for your PR
- The URL follows the pattern:
https://ai-tutor-api-pr-<number>.onrender.com
For example, PR #130 → https://ai-tutor-api-pr-130.onrender.com
Go to the Render Preview Environment for your PR:
- Navigate to Environment → Environment Variables
- Find
CORS_ORIGINS(or add it if missing) - Add your Vercel preview URL to the list:
Or if there are already origins in the list, append yours:["https://ai-tutor-<hash>-array-education.vercel.app"]["https://your-production-url.com","https://ai-tutor-<hash>-array-education.vercel.app"] - Alternative (easier): Set
CORS_ORIGIN_REGEXto match all Vercel previews:
This avoids updating CORS for every new PR. If this is already set, skip this step.https://ai-tutor.*\.vercel\.app - When prompted, trigger a redeploy so the new env var takes effect
Go to the Vercel dashboard:
- Navigate to Settings → Environment Variables
- Find
NEXT_PUBLIC_API_URL - For the Preview environment, set it to your Render preview URL:
https://ai-tutor-api-pr-<number>.onrender.com - Trigger a redeploy of the preview deployment:
- Go to the Deployments tab
- Find your preview deployment
- Click the ⋮ menu → Redeploy
- Make sure "Use existing build cache" is checked for speed
Important:
NEXT_PUBLIC_API_URLis baked in at build time (it's aNEXT_PUBLIC_variable). Changing the env var alone won't update an existing deployment — you must redeploy.
Once both services have redeployed with the updated env vars:
- Open the Vercel preview URL in your browser
- Open the browser DevTools → Network tab
- Try logging in or performing an action that hits the API
- Confirm that API requests go to
ai-tutor-api-pr-<number>.onrender.comand return 200 (not CORS errors or connection failures) - Check the Render preview logs to see incoming requests
| Symptom | Cause | Fix |
|---|---|---|
| CORS error in console | Backend doesn't have the Vercel preview URL in allowed origins | Update CORS_ORIGINS or CORS_ORIGIN_REGEX on Render, redeploy |
fetch fails / connection refused |
Frontend pointing to wrong backend URL | Check NEXT_PUBLIC_API_URL on Vercel, redeploy |
| API calls go to production backend | Vercel preview still using production NEXT_PUBLIC_API_URL |
Env var wasn't set for Preview environment, or deployment wasn't rebuilt |
| Auth failures (401) | Supabase project mismatch | Make sure both preview services point to the same Supabase project |
| Render preview doesn't exist | Missing label | Add the render-preview label to the PR |
- Vercel: Preview deployments are cleaned up automatically
- Render: Preview Environments are deleted automatically when the PR is closed/merged
No manual cleanup needed.
┌─────────────┐ NEXT_PUBLIC_API_URL ┌─────────────┐
│ Vercel │ ──────────────────────────────────▶ │ Render │
│ (frontend) │ │ (backend) │
│ │ ◀────────────────────────────────── │ │
└─────────────┘ CORS_ORIGINS / CORS_ORIGIN_REGEX└─────────────┘
Both links must be set correctly for the preview to work.
Frontend needs to know the backend URL (build-time env var).
Backend needs to allow the frontend origin (CORS).
Render preview only deploys when the `render-preview` label is on the PR.
- Vercel project: https://vercel.com/array-education/ai-tutor
- Render dashboard: https://dashboard.render.com (service:
ai-tutor-api) - Supabase: https://supabase.com/dashboard (check which project your previews use)