Vercel Deployment Spec
Vercel's pitch is that deployment is one button, and the pitch is honest. Connect the repo, push to main, the site is live. That is exactly why it needs a spec: the button works whether or not you have thought about what is behind it, and the failures it enables are quiet ones. The site deploys fine. It just happens to be talking to the wrong database.
The thing to internalize is that Vercel gives you three environments: Production, Preview, and Development. Every branch you push gets its own live Preview URL, which is genuinely great, and which also means every pull request is a running copy of your app. If that copy holds your production Stripe key, then every experiment, every half-finished agent branch, every "let me just try something" can charge a real card. Scoping environment variables per environment is not an advanced feature. It is the whole job.
Hand this spec to your agent to do the setup and wiring, but set the secret values in the Vercel dashboard yourself. An agent that never saw your production key cannot paste it somewhere it shouldn't. Fill in the brackets, then work the post-deploy checklist personally: the agent verifying its own deployment is the fox auditing the henhouse.
Prerequisites
- A Vercel account (the free Hobby tier is fine to start) connected to your GitHub account.
- Your project in a GitHub repo with a working local build.
- A purchased domain, only if you want a custom one. The `.vercel.app` URL works on day one.
# Deployment spec: [project name] on Vercel
Deploy this project to Vercel. Work in order. Show me the plan before any
step that changes Production.
## Project facts
- Framework: [Next.js 14 App Router / Vite + React / SvelteKit / other]
- Repo: [github.com/you/project]
- Package manager: [pnpm / npm / yarn]; builds must use the committed lockfile
- Build command: [framework default, unless you have a reason]
- Node version: [pin one, e.g. 20.x. "Whatever Vercel picks today" changes under you.]
## Environments
Treat these as three different apps that happen to share code:
- Production: deploys from [main]. Real domain, real data, live keys.
- Preview: auto-deploys every push to any other branch. Throwaway URL, test data, test keys.
- Development: local (`vercel dev` or your framework's dev server). Touches nothing shared.
## Environment variables
Set in the Vercel dashboard (Settings → Environment Variables), never committed
to the repo. The Environments column is the security model, not paperwork.
| Name | What it is | Environments | Secret? |
|---|---|---|---|
| DATABASE_URL | [production database] | Production only | yes |
| DATABASE_URL | [staging/branch database] | Preview only | yes |
| [SERVICE]_API_KEY | [live key, e.g. Stripe live] | Production only | yes |
| [SERVICE]_API_KEY | [test/sandbox key] | Preview + Development | yes |
| NEXT_PUBLIC_[NAME] | [browser-safe value only] | All | no |
Rules:
- Nothing secret ever gets a `NEXT_PUBLIC_` (or `VITE_`) prefix. That prefix
means "compile this into the JavaScript every visitor downloads."
- A Preview deployment must not be able to spend money or email a customer.
If it can, its keys are wrong.
- Confirm `.env.local` is in `.gitignore` before the first commit, not after.
## Domains
- Production domain: [yourdomain.com]
- Redirect: [www → apex, or apex → www. Pick one, permanently, and stop thinking about it.]
- DNS lives at: [registrar / Cloudflare / other]. After changing records, wait.
Do not debug propagation by changing more records.
## Preview flow (how a change reaches Production)
1. Branch off [main], push, open a pull request.
2. Vercel comments a Preview URL on the PR. Open it. Actually open it.
3. On the Preview URL, verify [the 3-5 things that must work: sign-in,
the page you changed, the flow that makes money]
4. Confirm the Preview is using test data (look at what it displays).
5. Merge. Production deploys from [main] automatically.
## Rollback (learn this before you need it)
Dashboard → Deployments → last known-good build → "Promote to Production."
It is instant because old builds are kept, not rebuilt. If Production breaks:
roll back first, diagnose second.
## Post-deploy verification (human does this, not the agent)
- [ ] Production URL loads over https with no mixed-content warnings
- [ ] One env-var-dependent path works end to end (log in, load real data)
- [ ] A Preview deployment shows test data, not production data
- [ ] The 404 page is yours, not Vercel's default
- [ ] Read the build log once, top to bottom. Warnings you ignore today are
the incident report you write later.Adaptation notes:
- Monorepo: set Root Directory in the Vercel project settings to the app's folder, or every deploy builds the wrong thing from the repo root.
- Not Next.js: the browser-exposure prefix changes (
VITE_for Vite,PUBLIC_for SvelteKit) but the rule is identical: prefixed means published. - If Previews show anything sensitive, turn on Vercel's deployment protection so Preview URLs require authentication. A Preview URL is guessable enough to treat as public.
- The classic mistake: adding an environment variable and expecting the running deployment to see it. Env vars are read at build time. Add the variable, then redeploy, then test.
- Pairs with §6.4: the spec names every secret but contains none. Keep it that way when you adapt it.