---
title: "Cloudflare Pages"
description: "Learn how to instrument a Cloudflare Pages application with Sentry using the sentryPagesPlugin middleware."
url: https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages/
---

# Cloudflare Pages | Sentry for Cloudflare

Cloudflare recommends [migrating to Workers with static assets](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/). Workers covers most Pages use cases with a broader feature set, and it's where new Cloudflare features land. Existing Pages projects will continue to work, so the guidance on this page remains accurate. For new projects, however, use Workers and follow the [Cloudflare guide](https://docs.sentry.io/platforms/javascript/guides/cloudflare.md) instead.

After migrating, use the Vite plugin or `withSentry` instead of `sentryPagesPlugin`, depending on your build setup.

Cloudflare Pages applications are instrumented with the `sentryPagesPlugin` middleware instead of the `withSentry` wrapper that Workers use. The rest of the SDK behaves the same, so the [Cloudflare guide](https://docs.sentry.io/platforms/javascript/guides/cloudflare.md) still applies for installation, Wrangler configuration, source maps, and the options reference.

## [Install](https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages.md#install)

```bash
npm install @sentry/cloudflare --save
```

*Other available variations of the above snippet: yarn, pnpm*

## [Configure](https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages.md#configure)

### [Wrangler Configuration](https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages.md#wrangler-configuration)

Since the SDK needs access to the `AsyncLocalStorage` API, you need to set the `nodejs_compat` compatibility flag and a `compatibility_date` of `2024-09-23` or later in your `wrangler.(jsonc|toml)` configuration file. We recommend the latest compatibility date, as some integrations depend on newer Cloudflare runtime features:

```jsonc
{
  // Set this to today's date
  "compatibility_date": "2026-09-15",
  "compatibility_flags": ["nodejs_compat"],
}
```

*Other available variations of the above snippet: Toml*

### [Release Configuration (Optional)](https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages.md#release-configuration-optional)

If you don't set the `release` option manually, the SDK automatically detects it from these sources (in order of priority):

1. The `SENTRY_RELEASE` environment variable
2. The `CF_VERSION_METADATA.id` binding (if configured)

To enable automatic release detection via Cloudflare's version metadata, add the `CF_VERSION_METADATA` binding in your wrangler configuration. This provides access to the [Cloudflare version metadata](https://developers.cloudflare.com/workers/runtime-apis/bindings/version-metadata/).

```jsonc
{
  // ...
  "version_metadata": {
    "binding": "CF_VERSION_METADATA",
  },
}
```

*Other available variations of the above snippet: Toml*

### [Add the Middleware](https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages.md#add-the-middleware)

To use the Sentry SDK, add the `sentryPagesPlugin` as [middleware to your Cloudflare Pages application](https://developers.cloudflare.com/pages/functions/middleware/).

Create a `_middleware.js` file in your [`functions` directory](https://developers.cloudflare.com/pages/functions/) (Cloudflare Pages [middleware](https://developers.cloudflare.com/pages/functions/middleware/)). Create the directory in the root of your project if it doesn't already exist, then create the file and import and initialize the Sentry Cloudflare SDK:

```javascript
import * as Sentry from "@sentry/cloudflare";

export const onRequest = [
  // Make sure Sentry is the first middleware
  Sentry.sentryPagesPlugin((context) => ({
    dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",

    dataCollection: {
      // Any dataCollection object (including {}) uses permissive defaults:
      // userInfo, cookies, HTTP bodies, genAI prompts/responses, and more.
      // Uncomment to tighten. Details:
      // https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/options/#dataCollection
      // userInfo: false,
      // httpBodies: [],
      // genAI: { inputs: false, outputs: false },
    },

    // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
    // Learn more at
    // https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/options/#tracesSampleRate
    tracesSampleRate: 1.0,
  })),
  // Add more middlewares here
];
```

Don't have access to onRequest?

If you don't have access to the `onRequest` middleware API, you can use the `wrapRequestHandler` API instead. For example:

```javascript
// hooks.server.js
import * as Sentry from "@sentry/cloudflare";

export const handle = ({ event, resolve }) => {
  const requestHandlerOptions = {
    options: {
      dsn: event.platform.env.SENTRY_DSN,
      tracesSampleRate: 1.0,
    },
    request: event.request,
    context: event.platform.ctx,
  };
  return Sentry.wrapRequestHandler(requestHandlerOptions, () =>
    resolve(event),
  );
};
```

## [Verify Your Setup](https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages.md#verify-your-setup)

Create a new route that throws an error when called by adding the following code snippet to a file in your `functions` directory, such as `functions/debug-sentry.js`:

```javascript
export async function onRequest(context) {
  throw new Error("My first Sentry error!");
}
```

To test your tracing configuration, start a span around the failing code:

```javascript
import * as Sentry from "@sentry/cloudflare";

export async function onRequest(context) {
  await Sentry.startSpan(
    {
      op: "test",
      name: "My First Test Span",
    },
    async () => {
      await new Promise((resolve) => setTimeout(resolve, 100)); // Wait for 100ms
      throw new Error("My first Sentry error!");
    },
  );
}
```

Then head over to your project on [Sentry.io](https://sentry.io) to view the collected data (it takes a couple of moments for the data to appear).

## [Known Limitations](https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/pages.md#known-limitations)

The [limitations of the Cloudflare Workers runtime](https://docs.sentry.io/platforms/javascript/guides/cloudflare.md#known-limitations) apply to Pages Functions as well, including zero-duration spans for CPU-bound work.
