title: Cloudflare category: Deploy order: 2
import Link from "../../../../components/Link.jsx";
Cloudflare
To deploy to Cloudflare Workers or Pages, use the built-in cloudflare adapter. This adapter is specifically designed to work with Cloudflare's edge runtime.
First you need to have a Cloudflare account with Workers enabled and the wrangler CLI installed:
npm install -g wrangler
wrangler login
No additional packages are needed - the adapter is built into @lazarv/react-server.
Then you need to add the adapter to your react-server.config.mjs file:
export default {
adapter: "cloudflare",
};
<Link name="configuration">
## Configuration
</Link>You can customize the adapter by passing options:
export default {
adapter: [
"cloudflare",
{
name: "my-app", // Cloudflare Worker name
compatibilityDate: "2024-01-01", // Cloudflare compatibility date
compatibilityFlags: ["nodejs_compat_v2"], // Additional compatibility flags
pages: true, // Generate _routes.json for Cloudflare Pages
excludeRoutes: ["/api/*"], // Additional routes to exclude from worker handling
serverlessFunctions: true, // Enable worker deployment (default: true)
wrangler: {
vars: {
MY_VAR: "value",
},
},
},
],
};
Configuration Options
name: Cloudflare Worker name. Falls back topackage.jsonname (without scope) or "react-server-app".compatibilityDate: Cloudflare compatibility date (default: current date).compatibilityFlags: Additional Cloudflare compatibility flags (appended to requirednodejs_compat).pages: Generate_routes.jsonfor Cloudflare Pages (default: true).excludeRoutes: Additional routes to exclude from worker handling in_routes.json.serverlessFunctions: Enable/disable worker deployment (default: true). Set tofalsefor static-only deployment.wrangler: Additional wrangler.toml configuration as an object (merged with adapter defaults).
To attach response headers to pre-rendered (ASSETS-served) pages — RFC 8288 Link headers for agent discovery, security headers, custom cache directives — drop a _headers file into your public/ directory. The runtime copies it to the static asset bundle at build time and Cloudflare applies it natively:
/*
Link: </.well-known/api-catalog>; rel="api-catalog"; type="application/linkset+json"
/secure/*
X-Frame-Options: DENY
Referrer-Policy: no-referrer
This works even when run_worker_first is enabled, as long as the worker proxies the request via env.ASSETS.fetch() (which the built-in adapter does) — the response is generated by the static-assets binding, not by the worker, so _headers rules are preserved end-to-end.
For headers that should also appear on worker-generated responses (SSR pages, content-negotiation responses, server functions, …) set them inside your middleware with setHeader from @lazarv/react-server. The _headers file does not apply to worker-generated responses.
By default Cloudflare serves static assets directly and only invokes your worker when no asset matches. If you need the worker to run before static assets — for example to do content negotiation between an HTML page and its .md sibling, set custom redirects, or apply auth in front of pre-rendered pages — enable run_worker_first in react-server.wrangler.toml:
[assets]
run_worker_first = true
The setting accepts either a boolean or an array of glob patterns (with ! for exclusion) to scope worker-first handling to specific routes:
[assets]
run_worker_first = ["/*", "!/assets/*", "!/client/*"]
The built-in worker proxies non-deferred requests through env.ASSETS.fetch(), so _headers continues to apply to those responses even with run_worker_first enabled. Worker-generated responses (SSR / content-negotiated alternatives) need to set their own headers from middleware.
To extend the generated wrangler.toml, create a react-server.wrangler.toml file in your project root. The adapter will merge it with its configuration:
- Primitive values: Adapter config takes precedence
- Objects: Deep merged recursively
- Arrays: Unique items from your config are preserved and prepended to adapter defaults
This allows you to add custom bindings, environment variables, or other Cloudflare-specific configuration while the adapter manages the required settings.
[vars]
MY_API_KEY = "secret"
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123"
<Link name="deploy">
## Deploy
</Link>When using @lazarv/react-server with the Cloudflare adapter, you can deploy your application using the following command:
pnpm react-server build [root] # [root] is the entry point of your application
wrangler deploy
You can also deploy with the react-server CLI by using the --deploy argument:
pnpm react-server build [root] --deploy
This will build your application and deploy it to Cloudflare Workers.
<Link name="cloudflare-pages"> ## Cloudflare Pages </Link>The adapter automatically generates a _routes.json file for Cloudflare Pages compatibility. This file specifies which routes should be handled by the Worker and which should be served as static assets.
By default, static assets like images, CSS, JavaScript, and fonts are excluded from Worker handling. You can add additional routes to exclude using the excludeRoutes option.
To deploy to Cloudflare Pages, you can use the Cloudflare dashboard or the wrangler pages commands.
Note: Some advanced Cloudflare features like Durable Objects, D1, and R2 bindings can be configured through the
react-server.wrangler.tomlfile. Please refer to the Cloudflare Workers documentation for more information about available features and configuration options.