Skip to content
← All insights
Vercel14 min read

Deploying Nuxt on Vercel without ignoring the runtime

How Nuxt build modes, Vercel deployments, functions, environment variables, data locality and observability shape a production application after the first successful deploy.

A successful deployment is only the first boundary

Vercel can build a connected Git repository and give each deployment a unique URL. That makes previewing a Nuxt change straightforward, but production readiness still depends on knowing which routes are static, which execute on the server and which external systems they call.

Treat the deployment summary as an architectural view: static assets, middleware and functions should match what the team believes it shipped. Unexpected functions or oversized bundles often reveal a rendering or import decision worth revisiting.

Choose build or generate from runtime needs

A normal Nuxt build can support SSR, static generation and platform features through Nitro. nuxt generate creates a fully static site and does not provide request-time SSR. Content sites can suit generation; authenticated or frequently changing server-rendered routes usually need a server build.

Do not choose generate only to avoid understanding server functions. Decide whether each route needs request-time data, user identity or immediate freshness, then select route rules and deployment output accordingly.

Keep the deployment preset explicit when usefultypescript / Nuxt
export default defineNuxtConfig({
  nitro: { preset: "vercel" },
  routeRules: {
    "/": { prerender: true },
    "/insights/**": { prerender: true },
    "/account/**": { ssr: true },
  },
})

Environment values belong to a deployment environment

Vercel separates development, preview and production values. A change applies to new deployments rather than retroactively changing an existing one. This makes deployments reproducible, but it also means rotating a credential requires a redeploy where the application reads it.

Keep secrets server-only and use Nuxt public runtime configuration only for values safe to expose. Preview environments should not silently share production databases, Auth0 callbacks or external write credentials.

Separate private and public runtime configurationtypescript / Nuxt
export default defineNuxtConfig({
  runtimeConfig: {
    databaseUrl: process.env.DATABASE_URL,
    auth0ClientSecret: process.env.AUTH0_CLIENT_SECRET,
    public: {
      baseUrl: process.env.NUXT_PUBLIC_BASE_URL,
    },
  },
})

Functions still have operational constraints

Serverless removes server management, not networking, concurrency or resource behaviour. A function that opens too many PostgreSQL connections, waits on a distant API or assumes a persistent writable filesystem can fail under real traffic.

Place compute close to its database where the platform permits and use connection behaviour suitable for the managed database. Keep long jobs out of request handlers and make external calls bounded by timeouts and useful errors.

Preview deployments need a verification purpose

A preview URL is valuable when it lets someone verify the actual build, routes and integration configuration before production. It is less useful when missing credentials cause every server path to fall back to mock behaviour.

Define which checks a preview supports, provide isolated test data where required and test direct page loads as well as client navigation. Authentication callback URLs and generated canonical metadata commonly differ between preview and production.

Observe cost and failure at the deployed boundary

Use function logs and platform observability to follow invocation volume, duration, errors and external requests. Add application correlation IDs so a browser failure can be traced through a Nuxt server route to a database or third-party API.

Production confidence includes rollback and configuration history. A previous deployment is useful only when its expected environment and compatible database schema still exist.