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 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:

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, longer cold starts, supports Node-only packages and long compute. Use it for image processing, PDF generation, Prisma, and anything that calls a Node-only library.

Set the runtime per route in Next.js with export const runtime = "edge" or "nodejs". Default routes to Node when in doubt; switch to Edge once you can prove the workload fits.

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.

// 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 cloudflare, set the records to DNS-only (grey cloud) on the verification record, then proxy the live record once Vercel validates.