Cloudflare
Deploy Nitro apps to Cloudflare.
#Cloudflare Workers
Preset: cloudflare_module
Note
Integration with this provider is possible with zero configuration supporting workers builds (beta).
The following shows an example nitro.config.ts file for deploying a Nitro app to Cloudflare Workers.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module"
})#Local Preview
You can use Wrangler to preview your app locally:
npm run buildnpx wrangler dev#Manual Deploy
After having built your application you can manually deploy it with Wrangler.
First make sure to be logged into your Cloudflare account:
npx wrangler loginThen you can deploy the application with:
npx wrangler deploy#Runtime Hooks
You can use runtime hooks below in order to extend Worker handlers.
#Additional Exports
You can add a exports.cloudflare.ts file to your project root to export additional handlers or properties to the Cloudflare Worker entrypoint.
export class MyWorkflow extends WorkflowEntrypoint {
async run(event: WorkflowEvent, step: WorkflowStep) {
// ...
}
}Nitro will automatically detect this file and include its exports in the final build.
Warning
The exports.cloudflare.ts file must not have a default export.
You can also customize the entrypoint file location using the cloudflare.exports option in your nitro.config.ts:
export default defineConfig({
cloudflare: {
exports: "custom-exports-entry.ts"
}
})#Scheduled Tasks (Cron Triggers)
When using Nitro tasks with scheduledTasks, Nitro automatically generates Cron Triggers in the wrangler config at build time.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
experimental: {
tasks: true,
},
scheduledTasks: {
"* * * * *": ["cms:update"],
"0 15 1 * *": ["db:cleanup"],
}
})No manual Wrangler configuration is needed - Nitro handles it for you.
#Tracing
🧪 Experimental!
When the experimental tracingChannel option is enabled, the Cloudflare presets report Nitro's tracing-channel events (h3 routes and middleware, srvx, unstorage operations, …) as custom spans, alongside Cloudflare's automatic instrumentation (fetch calls, KV reads, D1 queries, …) — no OpenTelemetry SDK required.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
tracingChannel: true,
});Tracing must be enabled on the Worker for spans to be recorded:
{
"observability": {
"traces": {
"enabled": true
}
}
}#Cloudflare Pages
Preset: cloudflare_pages
Note
Integration with this provider is possible with zero configuration.
Warning
Cloudflare Workers Module is the new recommended preset for deployments. Please consider using the pages only if you need specific features.
The following shows an example nitro.config.ts file for deploying a Nitro app to Cloudflare Pages.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_pages"
})Nitro automatically generates a _routes.json file that controls which routes get served from files and which are served from the Worker script. The auto-generated routes file can be overridden with the config option cloudflare.pages.routes (read more).
#Local Preview
You can use Wrangler to preview your app locally:
npm run buildnpx wrangler pages dev#Manual Deploy
After having built your application you can manually deploy it with Wrangler, in order to do so first make sure to be logged into your Cloudflare account:
npx wrangler loginThen you can deploy the application with:
npx wrangler pages deploy#Deploy within CI/CD using GitHub Actions
Regardless on whether you're using Cloudflare Pages or Cloudflare Workers, you can use the Wrangler GitHub actions to deploy your application.
Note
Note: Remember to instruct Nitro to use the correct preset (note that this is necessary for all presets including the cloudflare_pages one).
#Environment Variables
Nitro allows you to universally access environment variables using process.env or import.meta.env or the runtime config.
Note
Make sure to only access environment variables within the event lifecycle and not in global contexts since Cloudflare only makes them available during the request lifecycle and not before.
Example: If you have set the SECRET and NITRO_HELLO_THERE environment variables set you can access them in the following way:
import { defineHandler } from "nitro";
import { useRuntimeConfig } from "nitro/runtime-config";
console.log(process.env.SECRET) // note that this is in the global scope! so it doesn't actually work and the variable is undefined!
export default defineHandler((event) => {
// note that all the below are valid ways of accessing the above mentioned variables
useRuntimeConfig().helloThere
useRuntimeConfig().secret
process.env.NITRO_HELLO_THERE
import.meta.env.SECRET
});#Specify Variables in Development Mode
For development, you can use a .env or .env.local file to specify environment variables:
NITRO_HELLO_THERE="captain"
SECRET="top-secret"Note
Note: Make sure you add .env and .env.local to the .gitignore file so that you don't commit it as it can contain sensitive information.
#Specify Variables for local previews
After build, when you try out your project locally with wrangler dev or wrangler pages dev, in order to have access to environment variables you will need to specify the in a .dev.vars file in the root of your project (as presented in the Pages and Workers documentation).
If you are using a .env or .env.local file while developing, your .dev.vars should be identical to it.
Note
Note: Make sure you add .dev.vars to the .gitignore file so that you don't commit it as it can contain sensitive information.
#Specify Variables for Production
For production, use the Cloudflare dashboard or the wrangler secret command to set environment variables and secrets.
#Specify Variables using wrangler.toml/wrangler.json
You can specify a custom wrangler.toml/wrangler.json file and define vars inside.
Warning
Note that this isn't recommended for sensitive data like secrets.
Example:
# Shared
[vars]
NITRO_HELLO_THERE="general"
SECRET="secret"
# Override values for `--env production` usage
[env.production.vars]
NITRO_HELLO_THERE="captain"
SECRET="top-secret"#Direct access to Cloudflare bindings
Bindings are what allows you to interact with resources from the Cloudflare platform, examples of such resources are key-value data storages (KVs) and serverless SQL databases (D1s).
Tip
Nitro provides high level API to interact with primitives such as KV Storage and Database and you are highly recommended to prefer using them instead of directly depending on low-level APIs for usage stability.
In runtime, you can access bindings from the request event via event.req.runtime.cloudflare.env. This is for example how you can access a D1 binding:
import { defineHandler } from "nitro";
defineHandler(async (event) => {
const { env } = event.req.runtime.cloudflare
const stmt = await env.MY_D1.prepare('SELECT id FROM table')
const { results } = await stmt.all()
})#Access to the bindings in local dev
In development mode, Nitro emulates the Cloudflare environment using Miniflare (the same workerd runtime used by Wrangler and cloudflare workers in production). This means bindings are available natively from the request event — no separate proxy or wrangler installation is required.
To access bindings in dev mode, we first define them. You can do this in a wrangler.jsonc/wrangler.json/wrangler.toml file:
[vars]
MY_VARIABLE="my-value"
[[kv_namespaces]]
binding = "MY_KV"
id = "xxx"Alternatively, you can define bindings inline in your nitro.config.ts using the cloudflare.wrangler option (it accepts the same shape as wrangler.json):
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
cloudflare: {
wrangler: {
vars: {
MY_VARIABLE: "my-value",
},
kv_namespaces: [{ binding: "MY_KV", id: "xxx" }],
},
},
})From this moment, when running
npm run devyou will be able to access MY_VARIABLE and MY_KV from the request event just as illustrated above.
#Wrangler environments
If you have multiple Wrangler environments, you can specify which one to use during local dev emulation with the cloudflare.wranglerEnv option:
import { defineConfig } from "nitro";
export default defineConfig({
preset: 'cloudflare_module',
cloudflare: {
wranglerEnv: 'preview'
}
})