← Blog

Claude API Vercel Deployment Tutorial (Next.js)

2026-09-25 · 5 min read · SubToAPI Team

Deploying a Claude-powered app to Vercel involves three things most tutorials gloss over: where the API key lives, whether your route runs on the Node.js or Edge runtime, and how streaming responses behave once they leave your local machine. Get those three right and the deployment itself takes minutes.

This guide walks through a working Next.js App Router setup, from local development to a production deployment on Vercel, including the config that trips people up (timeouts, streaming, environment variable scoping).

Project Setup

Start with a fresh Next.js app or use an existing one:

npx create-next-app@latest claude-vercel-app
cd claude-vercel-app
npm install

Create an API route at app/api/chat/route.ts. This is the server-side code that talks to Claude — never call the Anthropic (or any LLM) API directly from client-side JavaScript, since that exposes your key in the browser bundle.

// app/api/chat/route.ts
export const runtime = "nodejs"; // or "edge" — see note below

export async function POST(req: Request) {
  const { message } = await req.json();

  const res = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "x-api-key": process.env.ANTHROPIC_API_KEY!,
      "anthropic-version": "2023-06-01",
    },
    body: JSON.stringify({
      model: "claude-3-5-sonnet-latest",
      max_tokens: 1024,
      messages: [{ role: "user", content: message }],
    }),
  });

  const data = await res.json();
  return Response.json(data);
}

Call this route from a client component with fetch("/api/chat", { method: "POST", body: ... }).

Environment Variables on Vercel

Local development uses .env.local, which Vercel ignores by design — it's gitignored and never uploaded. You need to set the variable separately in the dashboard:

  1. Open your project on vercel.com → Settings → Environment Variables
  2. Add the key (e.g. ANTHROPIC_API_KEY) with its value
  3. Choose which environments it applies to: Production, Preview, Development
  4. Redeploy — environment variable changes don't apply to already-built deployments

You can also set it via CLI:

vercel env add ANTHROPIC_API_KEY production

A common mistake is setting the variable only for Production and then wondering why preview deployments (from pull requests) fail with an auth error. Add it to all three scopes if you want previews to work.

Edge vs Node.js Runtime

Vercel functions can run on the standard Node.js runtime or the Edge runtime. This matters for a Claude API route:

For streaming chat responses, Edge is often preferred because it starts sending bytes to the client faster. But if your route does anything beyond a simple fetch — logging to a database, complex retry logic — Node.js is usually simpler to reason about.

Set the runtime explicitly at the top of your route file:

export const runtime = "edge";

Handling Streaming Responses

If you want Claude's response to stream token-by-token to the browser instead of waiting for the full completion, your route needs to proxy the stream rather than buffer it:

export const runtime = "edge";

export async function POST(req: Request) {
  const { message } = await req.json();

  const upstream = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "x-api-key": process.env.ANTHROPIC_API_KEY!,
      "anthropic-version": "2023-06-01",
    },
    body: JSON.stringify({
      model: "claude-3-5-sonnet-latest",
      max_tokens: 1024,
      stream: true,
      messages: [{ role: "user", content: message }],
    }),
  });

  return new Response(upstream.body, {
    headers: { "content-type": "text/event-stream" },
  });
}

Vercel supports this pattern natively on both runtimes — just make sure you don't accidentally await res.json() somewhere in the chain, which buffers the whole stream and defeats the purpose.

If you're building this for a product with multiple users or teams and want streaming, per-key usage metadata, and dashboard visibility without writing your own proxy layer, SubToAPI (/docs/streaming) gives you an HTTPS endpoint that handles the streaming plumbing so your Vercel route just forwards the request.

Deploying

Once your route works locally with npm run dev, deploy with:

vercel --prod

Or connect the GitHub repo in the Vercel dashboard for automatic deployments on every push. Vercel builds the app, applies your environment variables for the target environment, and gives you a production URL.

Check the Functions tab in the deployment logs if something fails — API errors from Anthropic (rate limits, invalid model names, malformed requests) show up there with the actual response body, which is more useful than the generic 500 Next.js shows in the browser.

Common Deployment Errors

Managing the API Key Across Environments

Teams often end up creating separate Anthropic keys per environment, then losing track of which one is live, which is staging, and who has access. If you want a single dashboard for issuing scoped API keys, streaming, and usage metadata across a team without managing raw provider keys in every environment variable panel, SubToAPI (/docs/quickstart) sits in front of your Claude access and gives each environment its own sub_live_... key you can revoke independently. Setup takes about the same steps as above — sign up (/signup), generate a key, drop it into Vercel's environment variables.

questions

Do I need a paid Vercel plan to run a Claude API route? No. The Hobby plan works for development and low-traffic apps, but it has stricter function timeout limits, which matters for long non-streaming completions. Streaming responses avoid most of that limitation.

Should I use the Edge or Node.js runtime for a chat route? Use Edge if you want lower latency and are only doing a simple fetch-and-stream. Use Node.js if your route needs npm packages, database writes, or more complex logic — it's more forgiving and easier to debug.

Why does my route work locally but fail after deploying to Vercel? Almost always an environment variable scoping issue — the key was added for Production but you're testing a Preview deployment, or it wasn't added at all. Check Settings → Environment Variables and redeploy after changes.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →