You can ship a full Nuxt 4 experience straight onto Cloudflare’s global edge. We’ve just finished migrating one of our projects to this setup, and the performance and simplicity have been excellent.

This blog walks through the key steps, highlights the important configuration files, and shares a few tips for working with Cloudflare Workers and Nuxt in tandem.

Why Cloudflare Workers for Nuxt

Cloudflare Workers give you low-latency, globally distributed execution without managing servers. When paired with Nuxt’s server-side rendering, you get:

  • Edge rendering – HTML is generated as close to the user as possible.
  • Automatic scaling – no pods or VMs to size or maintain.
  • Integrated caching & KV/R2 – Workers talk directly to Cloudflare’s storage for fast data access.
  • Nuxt Nitro compatibility – Nuxt 4 ships a Cloudflare Worker preset, so you rarely write platform-specific glue.

Prerequisites

  • recent Node.js and pnpm installed. (You can use npm or yarn, but this guide uses pnpm.)
  • A Cloudflare account with Workers enabled.
  • Wrangler CLI and login ahead (pnpm dlx wrangler login).
  • Optional: an R2 bucket if you want to use Cloudflare’s object storage. We use R2 to cache API responses in our app.

Project Layout Recap

.
├── app/               # Nuxt application source
├── server/api         # Server routes (Nitro endpoints)
├── wrangler.toml      # Worker deployment config
└── package.json       # Web app scripts (build, preview, deploy)

The root package.json adds worker-focused scripts (preview:worker, deploy:worker) so you can drive builds from the package.

Configure wrangler.toml

wrangler.toml tells Wrangler how to build and deploy the Worker. Key sections include:

name = "tinkink-demo-nuxt-worker"
main = ".output/server/index.mjs"
compatibility_date = "2025-10-22"
compatibility_flags = ["nodejs_compat"]
workers_dev = true

[assets]
directory = "./.output/public"

[build]
command = "pnpm build"

[[r2_buckets]]
binding = "R2_BUCKET"
bucket_name = "name-of-your-r2-bucket"
preview_bucket_name = "name-of-your-r2-bucket-for-preview"

Config Nuxt for Cloudflare

In nuxt.config.ts, set the Nitro preset to cloudflare-module so Nuxt builds a Worker-compatible bundle:

export default defineNuxtConfig({
  nitro: {
    preset: 'cloudflare-module',
  },
  // other Nuxt config...
});

Configure Environment Secrets

Our workers depend on secrets for upstream APIs. Store values in .env.local and .env.prod at the workspace root and expose them to Workers when developing or deploying.

{
    "scripts": {
        "build": "nuxt build",
        "preview:worker": "cat .env.local > .env && wrangler dev --config wrangler.toml",
        "deploy:worker": "cat .env.prod > .env && wrangler deploy --config wrangler.toml"
    }
}

During builds, package.json scripts copies env files into .env so Nuxt sees runtime credentials. Adjust or add variables as needed.

Build the Nuxt App for Workers

Nuxt uses Nitro to emit a Worker bundle when you target Cloudflare:

pnpm build

This produces a .output directory containing server/index.mjs, the Worker entrypoint. The build also respects wrangler.toml for binding declarations (KV, R2, Durable Objects) and environment settings.

Local Preview on the Edge Runtime

Wrangler can simulate the Worker runtime locally, letting you test server routes and caching behaviour:

pnpm preview:worker

The script runs wrangler dev --experimental-local against the generated Worker bundle. You get live reloads on server code and access to bindings like R2 if you configure them with --r2 <name> flags or in wrangler.toml.

Deploy to Cloudflare

Once the bundle is ready:

pnpm deploy:worker

Behind the scenes this runs wrangler deploy, uploading the Worker script plus any static assets. Check the Cloudflare dashboard for confirmation and logs.

If you prefer build & deploy in Cloudflare, connect your Git repo to Cloudflare Pages and set up a build command that runs pnpm build, and a deploy command that runs pnpm deploy:worker.

Working with Cloudflare Bindings

In the previous sections, we showed how to declare R2 buckets in wrangler.toml. You can also add other bindings like KV namespaces or Durable Objects.

To use a binding in your Nuxt app, reference it from the event object in server requests:

export default defineEventHandler(async (event: H3Event) => {
  const cloudflareEnv = event.context.cloudflare?.env?.R2_BUCKET;
  if (!cloudflareEnv)
    return null; // handle missing binding

  const obj = await r2.get('some-key');
  // ...
});

Summary

Deploying Nuxt on Cloudflare Workers combines the best of serverless edge computing with Nuxt’s powerful SSR capabilities. By configuring Nitro for Cloudflare, setting up Wrangler, and managing environment secrets, you can deliver a fast, scalable web app globally.