# 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.

## Installation

First you need to have a Cloudflare account with Workers enabled and the `wrangler` CLI installed:

```sh
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:

```mjs
export default {
  adapter: "cloudflare",
};
```

## Configuration

You can customize the adapter by passing options:

```mjs
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 to `package.json` name (without scope) or "react-server-app".
- `compatibilityDate`: Cloudflare compatibility date (default: current date).
- `compatibilityFlags`: Additional Cloudflare compatibility flags (appended to required `nodejs_compat`).
- `pages`: Generate `_routes.json` for Cloudflare Pages (default: true).
- `excludeRoutes`: Additional routes to exclude from worker handling in `_routes.json`.
- `serverlessFunctions`: Enable/disable worker deployment (default: true). Set to `false` for static-only deployment.
- `wrangler`: Additional wrangler.toml configuration as an object (merged with adapter defaults).

## Response headers

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`](https://developers.cloudflare.com/workers/static-assets/headers/) file into your `public/` directory. The runtime copies it to the static asset bundle at build time and Cloudflare applies it natively:

```text filename="public/_headers"
/*
  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`](#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.

## Worker-first request handling

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`:

```toml filename="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:

```toml filename="react-server.wrangler.toml"
[assets]
run_worker_first = ["/*", "!/assets/*", "!/client/*"]
```

The built-in worker proxies non-deferred requests through `env.ASSETS.fetch()`, so [`_headers`](#response-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.

## Extending Wrangler configuration

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.

```toml filename="react-server.wrangler.toml"
[vars]
MY_API_KEY = "secret"

[[kv_namespaces]]
binding = "MY_KV"
id = "abc123"
```

## Deploy

When using `@lazarv/react-server` with the Cloudflare adapter, you can deploy your application using the following command:

```sh
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:

```sh
pnpm react-server build [root] --deploy
```

This will build your application and deploy it to Cloudflare Workers.

## Cloudflare Pages

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.toml` file. Please refer to the [Cloudflare Workers documentation](https://developers.cloudflare.com/workers/) for more information about available features and configuration options.