Skip to main content
Engineering7 min readMarch 3, 2026

Zero-Config Nuxt Deployment on Vercel: What to Know Before You Ship

A complete guide to deploying Nuxt on Vercel — from initial setup to environment variables, edge functions, preview deployments, and the gotchas that catch developers by surprise.

James Ross Jr.

James Ross Jr.

Strategic Systems Architect & Enterprise Software Developer

Vercel is one of the best deployment platforms for Nuxt applications. The integration is genuinely good — connect a repository, configure a few settings, and you have a globally distributed application with preview deployments, automatic SSL, and a CDN in front of everything. For teams that value deployment simplicity, it is hard to beat.

But "zero-config" is a bit of a marketing claim. There are things to understand before you ship, particularly around environment variables, edge vs serverless functions, and the behavior differences between local development and Vercel's production environment.

Setting Up the Deployment

Import your repository into Vercel and configure the build settings:

Framework Preset: Nuxt.js (Vercel detects this automatically for most projects)

Build Command: npm run build (or pnpm build / yarn build)

Output Directory: .output (Nuxt's Nitro output — Vercel knows this)

Install Command: npm install

For most Nuxt projects, Vercel's auto-detection handles all of this correctly. The one setting worth verifying manually is the Node.js version. Go to Settings > General > Node.js Version and confirm it matches what you are using locally. Mismatched Node versions are a common source of deployment-only bugs.

Environment Variables

Vercel separates environment variables into three environments: Production, Preview, and Development. Configure them in Settings > Environment Variables.

Nuxt runtime config maps to environment variables by convention:

// nuxt.config.ts
runtimeConfig: {
  // Private — server only (no prefix)
  databaseUrl: '',        // Set via DATABASE_URL
  openaiKey: '',          // Set via OPENAI_KEY

  // Public — available client and server
  public: {
    apiBase: '',          // Set via NUXT_PUBLIC_API_BASE
    analyticsId: '',      // Set via NUXT_PUBLIC_ANALYTICS_ID
  },
},

The naming convention matters. Nuxt automatically maps NUXT_ prefixed variables to the corresponding runtimeConfig key. NUXT_DATABASE_URL maps to runtimeConfig.databaseUrl. NUXT_PUBLIC_API_BASE maps to runtimeConfig.public.apiBase.

Critical security note: Never put secret keys in runtimeConfig.public. These values are embedded in the client JavaScript bundle and are readable by anyone who views your page source. Only put values in public that are safe to expose.

Edge Functions vs Serverless Functions

Vercel offers two function runtimes for Nuxt: Edge Functions and Serverless Functions. The choice matters.

Serverless Functions are Node.js. They have the full Node.js API available, support larger bundles, and support the complete Nuxt/Nitro feature set. They have cold starts (a delay on the first request after a period of inactivity) but are otherwise highly compatible.

Edge Functions run on Vercel's Edge Network — V8-based, globally distributed, zero cold start. They are faster for most requests but have limitations: no Node.js APIs, 4MB bundle limit, limited filesystem access.

Configure which runtime Nuxt uses:

// nuxt.config.ts
nitro: {
  preset: 'vercel',           // Serverless Functions (default)
  // OR
  preset: 'vercel-edge',      // Edge Functions
},

I default to vercel (Serverless) unless I have a specific reason to use Edge. The compatibility is better, the debugging is easier, and cold starts are negligible for most application traffic patterns.

Use vercel-edge when: cold starts are unacceptable for your use case (real-time applications, APIs with SLA requirements), and you have verified your dependencies are compatible with the Edge runtime.

Per-Route Edge Configuration

Nuxt's routeRules gives you fine-grained control over caching and function runtime per route:

// nuxt.config.ts
routeRules: {
  '/': { prerender: true },           // Static — no function needed
  '/blog/**': { swr: 86400 },         // Cache for 24 hours
  '/api/**': { headers: { 'cache-control': 'no-store' } }, // No cache
  '/dashboard/**': { ssr: true },     // Always SSR
},

These rules map to Vercel's configuration automatically. prerender: true generates static HTML at build time and serves it from Vercel's CDN. swr: N configures stale-while-revalidate caching. This is the configuration that makes Nuxt on Vercel genuinely fast for content-heavy applications.

Preview Deployments

Every pull request gets a preview URL. This is one of Vercel's best features for team workflows. By default, preview deployments use the same environment variables as production. Override this for environment-specific values:

  • Go to Settings > Environment Variables
  • For each variable, choose which environments it applies to
  • Set NUXT_PUBLIC_API_BASE to your staging API URL for Preview environments

Be careful with databases. If your Preview deployments connect to production data, a bad deploy could corrupt production. Use a dedicated staging database for Preview environments or use branch databases (Neon, PlanetScale, and Supabase all support this).

Custom Domains

Add custom domains in Settings > Domains. Vercel handles SSL automatically via Let's Encrypt. Configure your DNS:

For apex domains (yourdomain.com): Add an A record pointing to Vercel's IP (76.76.19.61) or use Vercel's nameservers.

For subdomains (app.yourdomain.com): Add a CNAME record pointing to cname.vercel-dns.com.

Vercel's automatic SSL renewal means you never worry about certificate expiration. Set it up once and forget it.

Build Performance

For large Nuxt applications, builds on Vercel can be slow. Optimize them:

Enable build caching. Vercel caches the node_modules directory between builds. Make sure you are using a package-lock.json, yarn.lock, or pnpm-lock.yaml so the cache can be validated.

Use incremental static regeneration. Instead of pre-rendering every page at build time (which is slow), use swr rules to generate pages on demand and cache them.

Reduce unnecessary pre-rendering. Only pre-render pages that are high-traffic and truly static. Dynamic pages with user-specific content should use SSR or SWR, not pre-rendering.

Monitoring and Observability

Vercel's built-in Analytics provides real-user performance data (Core Web Vitals from real visitors, not just Lighthouse). Enable it in your project settings — it is worth the data.

For application monitoring, integrate with your observability stack:

// plugins/sentry.ts
export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig()

  if (config.public.sentryDsn) {
    Sentry.init({
      dsn: config.public.sentryDsn,
      environment: process.env.VERCEL_ENV || 'development',
      release: process.env.VERCEL_GIT_COMMIT_SHA,
    })
  }
})

Vercel exposes several useful environment variables automatically: VERCEL_ENV (production/preview/development), VERCEL_GIT_COMMIT_SHA, VERCEL_GIT_COMMIT_REF (branch name). Use these for release tracking and environment detection.

Common Gotchas

Filesystem writes fail silently. Serverless functions on Vercel have a read-only filesystem (except /tmp, which is ephemeral). Any code that writes files to disk — log files, generated content — will fail silently or with permissions errors. Use a database or object storage (S3, Cloudflare R2) instead.

Cold starts on infrequently visited routes. Serverless functions cold start after 15 minutes of inactivity. For applications where every route needs instant response, this is a problem. Solutions: edge functions (no cold start), keep-alive pings (a hack), or accept the cold start on infrequently visited pages.

Middleware and edge functions behave differently. Nuxt middleware that accesses browser APIs (window, document, localStorage) will fail if it runs in an edge function context. Guard these with process.client checks.

Bundle size limits. Serverless functions on Vercel have a 50MB compressed bundle limit. If you install many dependencies, check your bundle size. Use ANALYZE=true npm run build to find large dependencies.

Vercel and Nuxt together are an excellent combination for most web applications. The deployment workflow is genuinely good, the performance is solid, and the preview deployment feature alone is worth the platform lock-in for teams that collaborate on UI changes.


Deploying a Nuxt application on Vercel and running into infrastructure or configuration questions? I am happy to help troubleshoot. Book a call: calendly.com/jamesrossjr.


Keep Reading