Vercel Rules
Rule
Conventions for projects deployed on Vercel. See operations-playbook.md for the CI/env remediation shapes and env.md for the typed schema.
Environment Variables
- MUSTValidate every env var against the typed schema (
env.schema.ts) at startup — never readprocess.envraw in app code. - MUSTKeep the Vercel project env in sync with the schema. Run a drift check (diff schema's required keys against
vercel env ls) before promoting to production. - MUSTSet env vars per-environment (Development / Preview / Production) — don't reuse a production secret in preview.
- NEVERCommit
.env.local,.env.production, or OIDC tokens. They belong in Vercel's env store, not the repo. - SHOULDPrefer Vercel OIDC / connected-account tokens over long-lived secrets where the integration supports it.
Cron Routes
- MUSTDeclare scheduled work in
vercel.jsoncrons, not ad-hoc external schedulers. - MUSTAuthenticate every cron route. Verify a
CRON_SECRET(Vercel sends it asAuthorization: Bearer $CRON_SECRET) and reject unauthenticated calls — cron routes are public URLs. - MUSTAlert on cron failure. A cron route that 500s must surface it (issue, webhook, or monitored log), never fail silently. See operations-playbook (d).
- SHOULDKeep cron handlers idempotent — Vercel may retry, and schedules can overlap.
// app/api/cron/reconcile/route.ts
export async function GET(req: Request) {
if (req.headers.get("authorization") !== `Bearer ${process.env.CRON_SECRET}`) {
return new Response("Unauthorized", { status: 401 });
}
// ... idempotent work
return new Response("ok");
}
Deployment Flow
- MUSTShip through preview deployments first — every PR gets a preview URL; verify there before promoting.
- MUSTPromote a built preview to production (promote the deployment, don't rebuild) so what you tested is what ships.
- SHOULDKeep the gate (
pnpm check) green as a required check before merge — Vercel building green is not the same as the code gate passing. - SHOULDKnow the rollback path — promoting the previous production deployment is instant; use it rather than hotfix-forward under pressure.
vercel.json Hygiene
- MUSTKeep
vercel.jsonminimal and reviewed —crons,regions,headers,redirectsonly when they earn their place. - SHOULDPin
regionsdeliberately when the app is latency- or data-locality-sensitive; otherwise leave the default. - SHOULDSet security headers (CSP, HSTS,
X-Content-Type-Options) viaheadersor the framework, and keep them in one place. - NEVEREncode secrets or environment-specific values in
vercel.json— it's committed.