---
title: "Vercel Deployment"
slug: "vercel"
category: "ops"
tags: ["ops", "vercel", "ci", "edge"]
status: "stable"
last_updated: 2026-08-14
summary: "Project setup, environment scoping, edge vs node runtimes, previews, ISR, and the build cache."
related: ["[[frontend/nextjs]]", "[[frontend/astro]]", "[[ops/cloudflare]]", "[[ops/github-pages]]"]
---

## Overview

Vercel is the right host for Next.js apps and for any project that needs preview deployments, edge functions, or ISR. The platform auto-detects most frameworks, runs builds in a managed sandbox, and ships HTTPS for free. Reach for it when GitHub Pages runs out of room; reach past it to a VPS when egress or function minutes start to bite.

## Let the framework preset auto-detect

Connect the Git repo and accept the detected framework. Vercel maps Next.js, Astro, SvelteKit, Nuxt, Remix, and Vite to sane build commands, output directories, and runtime defaults. Override only when you know the preset is wrong. For Next.js, see [[frontend/nextjs]].

If the build command is non-standard, set it in `vercel.json` rather than in the dashboard. Source-controlled config survives team handoffs.

## Scope env vars per environment

Vercel exposes three environments: Development, Preview, and Production. Set each variable for the environments where it applies, not globally.

- Production secrets stay on Production only. A leaked preview should never carry the production database URL.
- Preview gets a separate database, a separate API key, and a separate analytics token.
- Development is for `vercel env pull` to populate a local `.env.local`.

Pull env vars locally with the CLI so dev parity stays honest:

```bash
vercel env pull .env.local
```

## Pick edge for latency, node for compute

Two runtimes ship by default. Choose by workload.

- Edge runtime: V8 isolates, global routing, sub-50ms cold starts, no Node APIs. Use it for auth checks, A/B routing, geolocated redirects, and small JSON responses.
- Node runtime: full Node.js, regional, supports Node-only packages and long compute. With Fluid compute (default on new projects), Node functions reuse warm instances across concurrent requests, closing most of the cold-start and cost gap that used to justify picking Edge.

Set the runtime per route in Next.js with `export const runtime = "edge"` or `"nodejs"`. Default routes to Node when in doubt; Vercel itself now recommends Node.js over Edge for most workloads, and Next.js 16.3+ ignores the `edge` runtime export entirely in the App Router. See [[ops/vercel-edge-functions]] for the constraints that still make Edge the right call in a shrinking set of cases.

## Every PR gets a preview URL

Vercel creates a preview deployment per commit on every branch and PR. The URL is stable for that commit and changes per push. Wire it into the GitHub PR with the Vercel app so reviewers click straight to the rendered output.

Treat previews as production. Run the same build, the same runtime, and the same env scope (Preview). The only difference is the database and the secrets.

## Use ISR for content that changes occasionally

Incremental Static Regeneration serves a static page and revalidates in the background after a window expires. Set `revalidate` on the page or route. See [[frontend/nextjs-caching]] for the wider revalidation model.

```ts
// app/blog/[slug]/page.tsx
export const revalidate = 3600 // seconds
```

ISR fits blogs, marketing pages, and product listings. Reach for on-demand revalidation (`revalidatePath`, `revalidateTag`) when a CMS webhook should force a refresh. Skip ISR for pages that depend on per-request data; use SSR or client fetches instead.

## Trust the build cache, prove it with the CLI

Vercel caches `node_modules`, `.next/cache`, and the framework's incremental build output across deploys. A clean rebuild from cache should be 2 to 5 times faster than a cold one. If builds run cold every time, check that the lockfile is committed and that the cache directories are not in `.vercelignore`.

Run `vercel build` locally to reproduce the build sandbox before you push. Local parity catches missing env vars, missing dependencies, and bad build commands before they burn deploy minutes.

## Domains and SSL come free

Add the domain in the project settings, point DNS at Vercel (apex `A` to `76.76.21.21` or `CNAME` for subdomains to `cname.vercel-dns.com`), and Vercel provisions a Let's Encrypt cert in minutes. For DNS routed through [[ops/cloudflare]], set the records to DNS-only (grey cloud) on the verification record, then proxy the live record once Vercel validates.

## Related

- [[frontend/nextjs]]
- [[frontend/astro]]
- [[ops/cloudflare]]
- [[ops/github-pages]]
