Skip to main content
Technology & EngineeringDeployment Hosting Services278 lines

Vercel Deployment

Vercel platform expertise — Next.js deployment, serverless/edge functions, environment variables, preview deployments, domains, and monorepo support

Quick Summary18 lines
Vercel is the platform built by the creators of Next.js, optimized for frontend frameworks with zero-configuration deployments. Every git push produces an immutable deployment with a unique URL. The platform embraces the "preview everything" model: every branch and PR gets its own live environment. Serverless and edge functions run close to users without managing infrastructure. The goal is to ship fast, preview confidently, and scale automatically.

## Key Points

- **Use edge runtime for latency-sensitive routes** — middleware, geolocation, A/B testing, and simple API responses run fastest at the edge.
- **Leverage ISR (Incremental Static Regeneration)** — set `revalidate` on pages to serve stale content while regenerating in the background.
- **Scope environment variables by environment** — use the Vercel dashboard to set different values for Production, Preview, and Development.
- **Protect preview deployments** — enable Vercel Authentication or use password protection for sensitive previews.
- **Use `CRON_SECRET`** — always validate the authorization header in cron endpoints to prevent unauthorized invocation.
- **Set `maxDuration`** — explicitly configure function timeout to avoid unexpected termination on long-running tasks.
- **Cache aggressively at the CDN** — use `s-maxage` and `stale-while-revalidate` headers on API responses that tolerate staleness.
- **Use Vercel KV or Blob for state** — avoid writing to the filesystem in serverless functions; use managed storage primitives instead.
- **Writing to `/tmp` expecting persistence** — serverless functions are stateless; files in `/tmp` disappear between invocations. Use a database or object store.
- **Deploying large monoliths as a single function** — split into multiple API routes. Each route becomes its own serverless function with independent scaling.
- **Hardcoding URLs instead of using `VERCEL_URL`** — this breaks preview deployments. Always derive base URLs from the environment.
- **Using `runtime: "edge"` with Node.js-only packages** — edge functions run V8, not Node.js. Libraries using `fs`, `net`, or native modules will fail.
skilldb get deployment-hosting-services-skills/Vercel DeploymentFull skill: 278 lines
Paste into your CLAUDE.md or agent config

Vercel Deployment

Core Philosophy

Vercel is the platform built by the creators of Next.js, optimized for frontend frameworks with zero-configuration deployments. Every git push produces an immutable deployment with a unique URL. The platform embraces the "preview everything" model: every branch and PR gets its own live environment. Serverless and edge functions run close to users without managing infrastructure. The goal is to ship fast, preview confidently, and scale automatically.

Setup

Project Initialization

// vercel.json — project configuration at repo root
{
  "buildCommand": "npm run build",
  "outputDirectory": ".next",
  "framework": "nextjs",
  "regions": ["iad1", "sfo1", "cdg1"],
  "env": {
    "NEXT_PUBLIC_API_URL": "@api-url"
  },
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Cache-Control", "value": "no-store" }
      ]
    }
  ]
}

CLI Deployment

// Install and link project
// $ npm i -g vercel
// $ vercel link
// $ vercel env pull .env.local

// Deploy preview
// $ vercel

// Deploy to production
// $ vercel --prod

Environment Variables

// vercel.json — reference Vercel environment variables
{
  "env": {
    "DATABASE_URL": "@database-url-production",
    "STRIPE_SECRET_KEY": "@stripe-secret"
  }
}

// Access in Next.js API route
// app/api/config/route.ts
import { NextResponse } from "next/server";

export async function GET() {
  // Server-side only — never prefix with NEXT_PUBLIC_
  const dbUrl = process.env.DATABASE_URL;
  return NextResponse.json({ status: "connected" });
}

Key Techniques

Serverless Functions

// app/api/users/route.ts — App Router API route (runs as serverless)
import { NextRequest, NextResponse } from "next/server";

export const runtime = "nodejs"; // default serverless runtime
export const maxDuration = 30; // seconds (Pro plan: up to 300)

export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams;
  const page = parseInt(searchParams.get("page") ?? "1", 10);

  const users = await fetchUsersFromDB(page);

  return NextResponse.json(users, {
    headers: { "Cache-Control": "s-maxage=60, stale-while-revalidate=300" },
  });
}

export async function POST(request: NextRequest) {
  const body = await request.json();
  const user = await createUser(body);
  return NextResponse.json(user, { status: 201 });
}

Edge Functions

// app/api/geo/route.ts — runs on Vercel Edge Network globally
import { NextRequest, NextResponse } from "next/server";

export const runtime = "edge";

export async function GET(request: NextRequest) {
  const country = request.headers.get("x-vercel-ip-country") ?? "US";
  const city = request.headers.get("x-vercel-ip-city") ?? "Unknown";
  const region = request.headers.get("x-vercel-ip-country-region") ?? "";

  return NextResponse.json({ country, city, region });
}

Middleware (Edge)

// middleware.ts — runs before every matched request at the edge
import { NextRequest, NextResponse } from "next/server";

export function middleware(request: NextRequest) {
  const token = request.cookies.get("session-token")?.value;

  if (request.nextUrl.pathname.startsWith("/dashboard") && !token) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  const response = NextResponse.next();
  response.headers.set("x-request-id", crypto.randomUUID());
  return response;
}

export const config = {
  matcher: ["/dashboard/:path*", "/api/protected/:path*"],
};

Preview Deployments and Branch Environments

// vercel.json — configure preview-specific behavior
{
  "git": {
    "deploymentEnabled": {
      "main": true,
      "staging": true
    }
  },
  "redirects": [
    {
      "source": "/old-page",
      "destination": "/new-page",
      "permanent": true
    }
  ]
}

// Use VERCEL_ENV to detect environment in code
// app/lib/config.ts
export function getConfig() {
  const env = process.env.VERCEL_ENV; // "production" | "preview" | "development"
  const url = process.env.VERCEL_URL; // auto-assigned deployment URL

  return {
    isProduction: env === "production",
    baseUrl: env === "production"
      ? "https://myapp.com"
      : `https://${url}`,
  };
}

Monorepo Support

// vercel.json at repo root for monorepo
{
  "projects": [
    {
      "name": "web",
      "rootDirectory": "apps/web",
      "framework": "nextjs"
    },
    {
      "name": "docs",
      "rootDirectory": "apps/docs",
      "framework": "nextjs"
    }
  ]
}

// turbo.json — Turborepo integration (auto-detected)
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    }
  }
}

Cron Jobs

// vercel.json — define cron schedules
{
  "crons": [
    {
      "path": "/api/cron/sync-data",
      "schedule": "0 */6 * * *"
    }
  ]
}

// app/api/cron/sync-data/route.ts
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  const authHeader = request.headers.get("authorization");
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  await syncExternalData();
  return NextResponse.json({ synced: true });
}

Custom Domains and Rewrites

// vercel.json
{
  "rewrites": [
    { "source": "/blog/:slug", "destination": "/api/blog/:slug" },
    { "source": "/app/:path*", "destination": "https://app.example.com/:path*" }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Frame-Options", "value": "DENY" },
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains" }
      ]
    }
  ]
}

Best Practices

  • Use edge runtime for latency-sensitive routes — middleware, geolocation, A/B testing, and simple API responses run fastest at the edge.
  • Leverage ISR (Incremental Static Regeneration) — set revalidate on pages to serve stale content while regenerating in the background.
  • Scope environment variables by environment — use the Vercel dashboard to set different values for Production, Preview, and Development.
  • Protect preview deployments — enable Vercel Authentication or use password protection for sensitive previews.
  • Use CRON_SECRET — always validate the authorization header in cron endpoints to prevent unauthorized invocation.
  • Set maxDuration — explicitly configure function timeout to avoid unexpected termination on long-running tasks.
  • Cache aggressively at the CDN — use s-maxage and stale-while-revalidate headers on API responses that tolerate staleness.
  • Use Vercel KV or Blob for state — avoid writing to the filesystem in serverless functions; use managed storage primitives instead.

Anti-Patterns

  • Writing to /tmp expecting persistence — serverless functions are stateless; files in /tmp disappear between invocations. Use a database or object store.
  • Deploying large monoliths as a single function — split into multiple API routes. Each route becomes its own serverless function with independent scaling.
  • Hardcoding URLs instead of using VERCEL_URL — this breaks preview deployments. Always derive base URLs from the environment.
  • Using runtime: "edge" with Node.js-only packages — edge functions run V8, not Node.js. Libraries using fs, net, or native modules will fail.
  • Ignoring function size limits — keep serverless function bundles under 50MB (250MB uncompressed). Tree-shake dependencies and avoid bundling unnecessary packages.
  • Skipping the build cache — avoid vercel --force in CI unless debugging; the cache dramatically speeds up builds.
  • Using getServerSideProps everywhere — prefer static generation or ISR when data does not change per-request. SSR on every request increases latency and cost.

Install this skill directly: skilldb add deployment-hosting-services-skills

Get CLI access →

Related Skills

AWS Lightsail

AWS Lightsail provides a simplified way to launch virtual private servers (VPS), containers, databases, and more. It's ideal for developers and small businesses needing easy-to-use, cost-effective cloud resources without deep AWS expertise.

Deployment Hosting Services264L

Cloudflare Pages Deployment

Cloudflare Pages and Workers expertise — edge-first deployments, full-stack apps with Workers functions, KV/D1/R2 bindings, preview URLs, custom domains, and global CDN distribution

Deployment Hosting Services312L

Coolify Deployment

Coolify self-hosted PaaS expertise — Docker-based deployments, Git integration, automatic SSL, database provisioning, server management, and Heroku/Netlify alternative on your own hardware

Deployment Hosting Services227L

Digital Ocean App Platform

DigitalOcean App Platform is a fully managed Platform-as-a-Service (PaaS) that allows you to quickly build, deploy, and scale web applications, static sites, APIs, and background services. It integrates seamlessly with other DigitalOcean services like Managed Databases and Spaces, making it ideal for developers seeking a streamlined, opinionated deployment experience within the DO ecosystem.

Deployment Hosting Services248L

Fly.io Deployment

Fly.io platform expertise — container deployment, global edge distribution, Dockerfiles, volumes, secrets, scaling, PostgreSQL, and multi-region patterns

Deployment Hosting Services338L

Google Cloud Run

Google Cloud Run is a fully managed serverless platform for containerized applications. It allows you to deploy stateless containers that scale automatically from zero to thousands of instances based on request load, paying only for the resources consumed. Choose Cloud Run for microservices, web APIs, and event-driven functions that require custom runtimes or environments.

Deployment Hosting Services223L