From 5e124f920921a36f0f5396767bbf26842280237e Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Fri, 11 Sep 2026 10:31:07 +0200 Subject: [PATCH] docs(cloudflare): Restructure the guide around the Vite setup Fixes what a new user hits between install and the first event, from the runtime docs audit (SDK-1426), and reorganizes the guide so the recommended Vite path leads. - Add the missing SDK import to the tracing verify snippets, which threw `ReferenceError: Sentry is not defined` when copied verbatim - Lead the quick start with the Vite plugin and an `instrument.server.ts` file, turning on the experimental `autoInstrumentation` and `useDiagnosticsChannelInjection` options - Add an Installation Methods section holding the Vite Plugin page, moved out of Features, and a new Wrangler page for the `withSentry` setup - Move the Cloudflare Pages setup to its own page, with a note recommending Workers with static assets - Move release detection and post-response spans to troubleshooting - Give the Hono framework page the real install and `app.use(sentry())` steps instead of a bare redirect - List the packages the plugin instruments at build time - Render `compatibility_date` from the build date with Cloudflare's "Set this to today's date" comment, instead of pinning the SDK minimum Co-Authored-By: Claude Opus 5 --- .../common/troubleshooting/index.mdx | 71 +++++ .../cloudflare/agent-tracing/agents-sdk.mdx | 4 +- .../guides/cloudflare/features/pages.mdx | 150 +++++++++ .../cloudflare/features/vite-plugin.mdx | 175 ----------- .../guides/cloudflare/frameworks/hono.mdx | 66 +++- .../javascript/guides/cloudflare/index.mdx | 293 ++++-------------- .../guides/cloudflare/install/index.mdx | 23 ++ .../guides/cloudflare/install/vite-plugin.mdx | 119 +++++++ .../guides/cloudflare/install/wrangler.mdx | 109 +++++++ .../how-to-use/javascript.cloudflare.mdx | 2 +- .../javascript.cloudflare.mdx | 32 +- redirects.js | 12 + 12 files changed, 623 insertions(+), 433 deletions(-) create mode 100644 docs/platforms/javascript/guides/cloudflare/features/pages.mdx delete mode 100644 docs/platforms/javascript/guides/cloudflare/features/vite-plugin.mdx create mode 100644 docs/platforms/javascript/guides/cloudflare/install/index.mdx create mode 100644 docs/platforms/javascript/guides/cloudflare/install/vite-plugin.mdx create mode 100644 docs/platforms/javascript/guides/cloudflare/install/wrangler.mdx diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index 21a367349d432b..813c80090facc4 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -691,4 +691,75 @@ shamefully-hoist=true + + + Cloudflare's [`waitUntil()`](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/#contextwaituntil) lets work continue after the Worker returns a response. Whether those spans arrive depends on your trace lifecycle. + + On the static lifecycle, which is the default, the SDK snapshots the request transaction when the response is returned, so anything finishing later is dropped. Streaming sends each sampled span as it finishes instead, which captures deferred work. + + Set `traceLifecycle: "stream"`, which needs `@sentry/cloudflare` version `10.49.0` or newer: + + ```javascript {filename:index.js} + export default Sentry.withSentry( + (env) => ({ + dsn: env.SENTRY_DSN, + tracesSampleRate: 1.0, + traceLifecycle: "stream", + }), + worker + ); + ``` + + If you need to keep the static lifecycle, wrap the background work in its own span with `forceTransaction: true`, which records it as a separate transaction. `forceTransaction` isn't available in stream mode. + + ```javascript {filename:index.js} + ctx.waitUntil( + Sentry.startSpan( + { name: "background.task", op: "task", forceTransaction: true }, + () => updateCacheAndDatabase() + ) + ); + ``` + + See Streamed Spans for how streaming changes filtering with `beforeSendSpan` and `ignoreSpans`. + + + + + The SDK resolves the release from the `release` option you pass, then the `SENTRY_RELEASE` environment variable, then the `CF_VERSION_METADATA.id` binding. The first one that is set wins. Reading the binding automatically needs `@sentry/cloudflare` version `10.35.0` or newer; on earlier versions, pass it as the `release` option yourself, as shown at the end of this entry. + + If your events carry no release, check that the binding is declared in your wrangler config: + + ```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} + { + "version_metadata": { + "binding": "CF_VERSION_METADATA" + } + } + ``` + + ```toml {tabTitle:Toml} {filename:wrangler.toml} + [version_metadata] + binding = "CF_VERSION_METADATA" + ``` + + The binding only carries a meaningful version ID on a deployed Worker. In local development the value is [not applicable or accurate](https://developers.cloudflare.com/workers/local-development/), so events from `wrangler dev` or `vite dev` won't match a release in Sentry. + + If your events carry a release you didn't expect, something further up the list is set. A `SENTRY_RELEASE` variable left over in your Worker's environment overrides the binding, and an explicit `release` option overrides both. + + To pin the release to the Cloudflare version ID no matter what else is set, pass it yourself: + + ```javascript + Sentry.withSentry( + (env) => ({ + dsn: "___PUBLIC_DSN___", + release: env.CF_VERSION_METADATA?.id, + }) + // ... + ); + ``` + + + + If you need additional help, you can [ask on GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose). Customers on a paid plan may also contact support. diff --git a/docs/platforms/javascript/guides/cloudflare/agent-tracing/agents-sdk.mdx b/docs/platforms/javascript/guides/cloudflare/agent-tracing/agents-sdk.mdx index 82fbb3876e713a..d74c495d476091 100644 --- a/docs/platforms/javascript/guides/cloudflare/agent-tracing/agents-sdk.mdx +++ b/docs/platforms/javascript/guides/cloudflare/agent-tracing/agents-sdk.mdx @@ -36,7 +36,7 @@ export const MyAgent = Sentry.instrumentAgentWithSentry( The Worker that calls the agent names its binding in `rpcTracePropagationBindings`. See RPC Trace Propagation. -`instrumentAgentWithSentry` works with `Agent` from `agents`, `AIChatAgent` from `@cloudflare/ai-chat`, and `McpAgent` from `agents/mcp`. When you build with the Sentry Cloudflare Vite plugin's `autoInstrumentation`, the plugin detects and wraps Agent classes automatically. +`instrumentAgentWithSentry` works with `Agent` from `agents`, `AIChatAgent` from `@cloudflare/ai-chat`, and `McpAgent` from `agents/mcp`. When you build with the Sentry Cloudflare Vite plugin's `autoInstrumentation`, the plugin detects and wraps Agent classes automatically. ## Conversation IDs @@ -93,7 +93,7 @@ Populate the Conversations **User** column with `Sentry.setUser` on every reques - Workers AI - Durable Objects -- Vite Plugin +- Vite Plugin - Tracking Conversations diff --git a/docs/platforms/javascript/guides/cloudflare/features/pages.mdx b/docs/platforms/javascript/guides/cloudflare/features/pages.mdx new file mode 100644 index 00000000000000..0e828df487bd24 --- /dev/null +++ b/docs/platforms/javascript/guides/cloudflare/features/pages.mdx @@ -0,0 +1,150 @@ +--- +title: Cloudflare Pages +description: "Learn how to instrument a Cloudflare Pages application with Sentry using the sentryPagesPlugin middleware." +--- + + + +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. Pages keeps working, so this page stays accurate, but start new projects on Workers and follow the Cloudflare guide instead. + +After migrating, you replace `sentryPagesPlugin` with the Vite plugin or `withSentry`, depending on how you build. + + + +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 still applies for installation, Wrangler configuration, source maps, and the options reference. + +## Install + + + +## Configure + +### Wrangler Configuration + + + +### 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/). + + + + + + +```javascript {filename:functions/_middleware.js} +import * as Sentry from "@sentry/cloudflare"; + +export const onRequest = [ + // Make sure Sentry is the first middleware + Sentry.sentryPagesPlugin((context) => ({ + dsn: "___PUBLIC_DSN___", + + 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 +]; +``` + + + + + + + + + + +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 + + + + + +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 {filename:debug-sentry.js} +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 {filename:debug-sentry.js} +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 + +The limitations of the Cloudflare Workers runtime apply to Pages Functions as well, including zero-duration spans for CPU-bound work. diff --git a/docs/platforms/javascript/guides/cloudflare/features/vite-plugin.mdx b/docs/platforms/javascript/guides/cloudflare/features/vite-plugin.mdx deleted file mode 100644 index e760be1efdf987..00000000000000 --- a/docs/platforms/javascript/guides/cloudflare/features/vite-plugin.mdx +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: Vite Plugin -description: "Learn how to use the Sentry Cloudflare Vite plugin to instrument bundled dependencies at build time." ---- - - - - - The Sentry Cloudflare Vite plugin has **experimental** stability. - Configuration options and behavior may change or be removed in any release. - - -The Sentry Cloudflare Vite plugin (`sentryCloudflareVitePlugin`) instruments your Worker at build time. It can: - -1. **Instrument bundled dependencies**: automatically instruments supported packages in your bundle (such as database clients like `mysql`) at build time, giving you more traces out of the box. -2. **Auto-instrument your Worker entry**: optionally wraps your default export with `Sentry.withSentry()`, and Durable Object, Workflow, and Agents SDK classes with the matching `instrument*WithSentry` helper at build time, so you don't need to modify your code. - -**We recommend building your Cloudflare Worker with Vite and the `sentryCloudflareVitePlugin` plugin.** It's the most complete way to get tracing for bundled dependencies in the Workers runtime. If you already deploy with `wrangler` directly, see [Migrating From Wrangler](#migrating-from-wrangler). - -## Install - -The Vite plugin ships with `@sentry/cloudflare`, so there's no extra package to install. It's designed to run alongside the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/). - -## Prerequisites - -The plugin relies on Node.js APIs (`diagnostics_channel`) at runtime, so your Worker must have the `nodejs_compat` compatibility flag enabled. See Node.js Compatibility Entrypoint for setup. - -## Configure - -Enable `useDiagnosticsChannelInjection` to trace supported bundled dependencies, and wrap your handler with `withSentry` as usual: - -```typescript {filename:vite.config.ts} -import { cloudflare } from "@cloudflare/vite-plugin"; -import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; -import { defineConfig } from "vite"; - -export default defineConfig({ - plugins: [ - cloudflare(), - sentryCloudflareVitePlugin({ - _experimental: { - useDiagnosticsChannelInjection: true, - }, - }), - ], -}); -``` - -```typescript {filename:index.ts} -import * as Sentry from "@sentry/cloudflare"; - -export default Sentry.withSentry( - (env) => ({ - dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, - }), - { - async fetch(request, env) { - // Spans from bundled dependencies (such as mysql) are captured automatically - return new Response("..."); - }, - } -); -``` - -### Auto-instrumentation (Experimental) - -Alternatively, the plugin can wrap your Worker for you at build time, so you don't need `withSentry` in your code. Enable `autoInstrumentation` and the plugin reads your wrangler config (probing `wrangler.json`, `wrangler.jsonc`, and `wrangler.toml` at the Vite root, or the file set with [`wranglerConfigPath`](#options)) to find the entry point, Durable Objects, workflows, and Agents SDK classes. The plugin wraps Agents SDK classes (`Agent`, `AIChatAgent`, `McpAgent`) with `instrumentAgentWithSentry` (SDK version 10.69.0 or higher), which also gives them automatic conversation IDs (see Cloudflare Agents SDK). - -```typescript {filename:vite.config.ts} -import { cloudflare } from "@cloudflare/vite-plugin"; -import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; -import { defineConfig } from "vite"; - -export default defineConfig({ - plugins: [ - cloudflare(), - sentryCloudflareVitePlugin({ - _experimental: { - autoInstrumentation: true, - useDiagnosticsChannelInjection: true, - }, - }), - ], -}); -``` - -With auto-instrumentation, you can optionally provide Sentry options via a co-located `instrument.server.*` file (`.ts`, `.mts`, `.js`, `.mjs`, or `.cjs`) next to your Worker entry. The plugin resolves this location from `main` in your wrangler config. For example, if `main` is `src/worker/index.ts`, place the file at `src/worker/instrument.server.ts`, not at the project root. Use `defineCloudflareOptions` for full type-checking: - -```typescript {filename:instrument.server.ts} -import { defineCloudflareOptions } from "@sentry/cloudflare"; - -export default defineCloudflareOptions((env) => ({ - dsn: env.SENTRY_DSN, - tracesSampleRate: 1.0, -})); -``` - -If no `instrument.server.*` file exists, the SDK reads all configuration (DSN, release, environment, sample rate, etc.) from the Worker's `env` bindings at runtime. - -Configured Durable Object, Workflow, and Agents SDK classes must be declared in the Worker entry for the plugin to wrap them automatically. The plugin cannot rewrite a class that the entry only imports or re-exports from another module. In that case, wrap the imported class in the entry with its matching helper and pass it the options callback from `instrument.server.*`: - -```typescript {filename:src/worker/index.ts} -import * as Sentry from "@sentry/cloudflare"; -import sentryOptions from "./instrument.server"; -import { MyAgent as MyAgentBase } from "./my-agent"; - -export const MyAgent = Sentry.instrumentAgentWithSentry( - sentryOptions, - MyAgentBase -); -``` - -Use `instrumentDurableObjectWithSentry` for a plain Durable Object or `instrumentWorkflowWithSentry` for a Workflow. - -#### Derived RPC Trace Propagation - - - -The plugin knows which bindings point at classes it wrapped itself: Durable Object bindings without a `script_name`, and service bindings naming this Worker. Those receivers are guaranteed to strip the trailing trace argument again, so the plugin adds their binding names to `rpcTracePropagationBindings`, which covers the calling and the receiving side alike. Traces then connect across RPC calls within one deployment, with no configuration of your own. - -Bindings to *other* Workers stay opt-in, because their receivers may not run Sentry. List those yourself in `instrument.server.*`; whatever you list is added on top of the derived names. See RPC Trace Propagation. - -The plugin derives only the classes it wrapped itself. A class you wrapped by hand, or one re-exported from another module, runs on its own options and stays out. - -This applies to Vite builds only. At runtime a `DurableObjectNamespace` exposes no origin and a `Fetcher` does not say which service it points at, so a plain wrangler build still has to list its bindings. - -## Options - - - -Path to your wrangler config file. By default the plugin probes `wrangler.json`, `wrangler.jsonc`, and `wrangler.toml` at the Vite root. Set this when your config lives at a custom path, for example to mirror the `configPath` option of the Cloudflare Vite plugin: - -```typescript {filename:vite.config.ts} -export default defineConfig({ - plugins: [ - cloudflare({ configPath: "./wrangler.agent.jsonc" }), - sentryCloudflareVitePlugin({ - wranglerConfigPath: "./wrangler.agent.jsonc", - _experimental: { - autoInstrumentation: true, - }, - }), - ], -}); -``` - - - - - -Experimental options that may change or be removed without notice. - - - - - -Automatically wraps your Worker at build time so you don't have to edit your entry. The plugin reads your wrangler config, wraps the default export with `Sentry.withSentry()` (sourcing options from a co-located `instrument.server.*` file, falling back to `env`), and wraps configured classes with the matching helper: Durable Objects with `instrumentDurableObjectWithSentry`, Workflows with `instrumentWorkflowWithSentry`, and Agents SDK classes with `instrumentAgentWithSentry` (SDK version 10.69.0 or higher). Both `vite build` and `vite dev` are instrumented. The plugin also adds the bindings that resolve to the wrapped classes to `rpcTracePropagationBindings` (SDK version 10.72.0 or higher). - - - - - -Enables build-time automatic instrumentation of supported dependencies. When enabled, the plugin injects `diagnostics_channel` calls into bundled packages during both `vite build` and `vite dev`. When disabled or omitted, the plugin is a no-op. - - - -## Migrating From Wrangler - -If you deploy with `wrangler` directly, moving to Vite is straightforward: - -1. Set up the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/get-started/) and add a `vite.config.ts` with the `cloudflare()` and `sentryCloudflareVitePlugin()` plugins as shown above. -2. Run `vite build` before `wrangler deploy`, and use `vite dev` in place of `wrangler dev` for local development. - -Your existing `wrangler.jsonc` becomes the input config, and the plugin generates the deployed output during the build. For the full list of fields that change or become redundant, see Cloudflare's [Migrating from Wrangler](https://developers.cloudflare.com/workers/vite-plugin/reference/migrating-from-wrangler-dev/) guide. diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/hono.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/hono.mdx index 75545c313dfa28..6a7df59814d506 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/hono.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/hono.mdx @@ -3,6 +3,68 @@ title: Hono on Cloudflare description: "Learn how to instrument your Hono app on Cloudflare Workers with Sentry." --- -Hono has its own dedicated SDK (`@sentry/hono`) with first-class support for Cloudflare Workers, Node.js, Bun, and Deno. +Hono has its own dedicated SDK (`@sentry/hono`) with first-class support for Cloudflare Workers, Node.js, Bun, and Deno. It works as Hono middleware, so you can drop it into an existing app. -For setup instructions, see the **[Hono Quick Start Guide](/platforms/javascript/guides/hono/)**. +## Install + +Install `@sentry/hono` together with `@sentry/cloudflare`. The runtime package is a peer dependency that you never import directly, but it must be present and its version must match `@sentry/hono`. + +```bash {tabTitle:npm} +npm install @sentry/hono @sentry/cloudflare +``` + +```bash {tabTitle:yarn} +yarn add @sentry/hono @sentry/cloudflare +``` + +```bash {tabTitle:pnpm} +pnpm add @sentry/hono @sentry/cloudflare +``` + +## Configure + +The SDK needs `AsyncLocalStorage`, so set the `nodejs_compat` compatibility flag and a `compatibility_date` of `2024-09-23` or later in your Wrangler configuration: + +```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} +{ + // Set this to today's date + "compatibility_date": "{{@inject new Date().toISOString().slice(0, 10) }}", + "compatibility_flags": ["nodejs_compat"], +} +``` + +```toml {tabTitle:Toml} {filename:wrangler.toml} +# Set this to today's date +compatibility_date = "{{@inject new Date().toISOString().slice(0, 10) }}" +compatibility_flags = ["nodejs_compat"] +``` + +Add the `sentry()` middleware as early as possible in your Hono app, before any route that you want covered: + +```typescript {filename:index.ts} +import { Hono } from "hono"; +import { sentry } from "@sentry/hono/cloudflare"; + +const app = new Hono(); + +app.use( + sentry(app, { + dsn: "___PUBLIC_DSN___", + + // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing. + tracesSampleRate: 1.0, + }) +); + +// Your routes here + +export default app; +``` + +To read the DSN from a Worker binding, pass a callback instead of a plain options object. The callback receives the Worker `env`: + +```typescript {filename:index.ts} +app.use(sentry(app, (env) => ({ dsn: env.SENTRY_DSN }))); +``` + +For the full setup, including verification and the other runtimes, see the **[Hono Quick Start Guide](/platforms/javascript/guides/hono/)**. diff --git a/docs/platforms/javascript/guides/cloudflare/index.mdx b/docs/platforms/javascript/guides/cloudflare/index.mdx index 5acdf2afcd7d25..9b14a49c51b738 100644 --- a/docs/platforms/javascript/guides/cloudflare/index.mdx +++ b/docs/platforms/javascript/guides/cloudflare/index.mdx @@ -1,6 +1,6 @@ --- title: Cloudflare -description: "Learn how to manually set up Sentry for Cloudflare Workers and Cloudflare Pages and capture your first errors." +description: "Learn how to manually set up Sentry for Cloudflare Workers and capture your first errors." sdk: sentry.javascript.cloudflare categories: - javascript @@ -11,7 +11,9 @@ categories: -Use this guide for general instructions on using the Sentry SDK with Cloudflare. If you're using any of the listed frameworks, follow their specific setup instructions: +This guide covers Cloudflare Workers. If you're deploying a Cloudflare Pages application, see Cloudflare Pages instead, which is set up with middleware rather than a wrapper. + +If you're using any of the listed frameworks, follow their specific setup instructions: - **[Astro](/platforms/javascript/guides/cloudflare/frameworks/astro/)** - **[Hono](/platforms/javascript/guides/hono/)** (with @sentry/hono) @@ -66,174 +68,105 @@ Importing Sentry from the `@sentry/cloudflare/nodejs_compat` entrypoint unlocks ## Configure -The main Sentry configuration should happen as early as possible in your app's lifecycle. - -### Build Tooling - -We recommend building your Worker with **Vite** and the Sentry Cloudflare Vite plugin. It instruments bundled dependencies (like database clients) at build time, giving you more traces in the Cloudflare Workers runtime, where runtime monkey-patching isn't available. If you deploy with `wrangler` directly, everything below still works — you just miss out on that build-time instrumentation. - -With Vite, add the plugin to your `vite.config.ts`, then run `vite build` before `wrangler deploy`. With plain Wrangler, there's no extra build step. - -```typescript {tabTitle:Vite (Recommended)} {filename:vite.config.ts} {mdExpandTabs} -import { cloudflare } from "@cloudflare/vite-plugin"; -import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; -import { defineConfig } from "vite"; - -export default defineConfig({ - plugins: [ - cloudflare(), - sentryCloudflareVitePlugin({ - _experimental: { - useDiagnosticsChannelInjection: true, - }, - }), - ], -}); -``` - -```bash {tabTitle:Wrangler} -# No extra build tooling — deploy with wrangler as usual: -wrangler deploy - -# You can switch to Vite later. See the Migrating From Wrangler guide: -# https://docs.sentry.io/platforms/javascript/guides/cloudflare/features/vite-plugin/#migrating-from-wrangler -``` +This guide sets Sentry up through Vite, which is what we recommend for Cloudflare Workers. The plugin does the wiring at build time, so your Worker code stays untouched. -See the Vite plugin docs for options and migration steps. + -### Wrangler Configuration +Not using Vite? See the Wrangler setup for the manual instrumentation. - + -### Setup for Cloudflare Workers +### Add the Vite Plugin -Wrap your exported handler with `Sentry.withSentry()` to start capturing errors and traces from your Worker: +Add the Sentry plugin to your existing `vite.config.ts`, next to `cloudflare()`. Both behaviors are experimental in this version, so turn them on explicitly. + +`autoInstrumentation` wraps your Worker entry, and any Durable Object, Workflow or Agents SDK class in your wrangler config, at build time, so you don't have to call `Sentry.withSentry()` yourself. `useDiagnosticsChannelInjection` instruments bundled dependencies such as database clients, which is the only way to trace them in the Workers runtime, where the SDK can't patch them at runtime. + +To see its options, which packages it instruments, and how to opt out of either behavior, see Vite Plugin. -```typescript {filename:index.ts} -import * as Sentry from "@sentry/cloudflare"; - -export default Sentry.withSentry( - (env: Env) => ({ - dsn: "___PUBLIC_DSN___", - - 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 }, - }, - // ___PRODUCT_OPTION_START___ performance - - // 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, - // ___PRODUCT_OPTION_END___ performance - }), - { - async fetch(request, env, ctx) { - // Your worker logic here - return new Response("Hello World!"); - }, - } -); +```typescript {filename:vite.config.ts} {diff} + import { cloudflare } from "@cloudflare/vite-plugin"; ++import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; + import { defineConfig } from "vite"; + + export default defineConfig({ + plugins: [ + cloudflare(), ++ sentryCloudflareVitePlugin({ ++ _experimental: { ++ autoInstrumentation: true, ++ useDiagnosticsChannelInjection: true, ++ }, ++ }), + ], + }); ``` -If you're using the Sentry Cloudflare Vite plugin, its experimental `autoInstrumentation` option can wrap your Worker for you at build time, so you don't need `withSentry` in your code. +Run `vite build` before `wrangler deploy`, and use `vite dev` in place of `wrangler dev` for local development. -### Setup for Cloudflare Pages +### Wrangler Configuration + + + +### Add Your Sentry Options -To use the Sentry SDK, add the `sentryPagesPlugin` as [middleware to your Cloudflare Pages application](https://developers.cloudflare.com/pages/functions/middleware/). +Create an `instrument.server.ts` file next to your Worker entry, the file that `main` points at in your wrangler config. If `main` is `src/index.ts`, the file belongs at `src/instrument.server.ts`, not at the project root. - +The name is fixed. The plugin looks for `instrument.server` with a `.ts`, `.mts`, `.js`, `.mjs` or `.cjs` extension, and passes its default export to `withSentry`. Use `defineCloudflareOptions` to get the options type-checked. -```javascript {filename:functions/_middleware.js} -import * as Sentry from "@sentry/cloudflare"; +```typescript {filename:src/instrument.server.ts} +import { defineCloudflareOptions } from "@sentry/cloudflare"; + +export default defineCloudflareOptions((env) => ({ + dsn: "___PUBLIC_DSN___", -export const onRequest = [ - // Make sure Sentry is the first middleware - Sentry.sentryPagesPlugin((context) => ({ - dsn: "___PUBLIC_DSN___", - - 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 }, - }, - // ___PRODUCT_OPTION_START___ performance - - // 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, - // ___PRODUCT_OPTION_END___ performance - })), - // Add more middlewares here -]; + 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 }, + }, + // ___PRODUCT_OPTION_START___ performance + + // 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, + // ___PRODUCT_OPTION_END___ performance +})); ``` - - - - + -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)); -}; -``` - - - - +If you don't add an `instrument.server.*` file, the SDK reads its configuration from the Worker's `env` at runtime instead: `SENTRY_DSN`, `SENTRY_ENVIRONMENT`, `SENTRY_TRACES_SAMPLE_RATE`, `SENTRY_DEBUG`, `SENTRY_TUNNEL` and `SENTRY_TRACE_LIFECYCLE`. Set them as secrets or vars in your wrangler config. @@ -253,8 +186,6 @@ Let's test your setup and confirm that Sentry is working correctly and sending d First, let's make sure Sentry is correctly capturing errors and creating issues in your project. -#### Cloudflare Workers - @@ -283,34 +214,13 @@ export default { -#### Cloudflare Pages - - - - - -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 {filename:debug-sentry.js} -export async function onRequest(context) { - throw new Error("My first Sentry error!"); -} -``` - - - - - ### Tracing To test your tracing configuration, update the previous code snippet by starting a trace to measure the time it takes to run your code. -#### Cloudflare Workers - ```javascript {filename:index.js} +import * as Sentry from "@sentry/cloudflare"; + export default { async fetch(request) { const url = new URL(request.url); @@ -319,7 +229,7 @@ export default { await Sentry.startSpan( { op: "test", - name: "My First Test Transaction", + name: "My First Test Span", }, async () => { await new Promise((resolve) => setTimeout(resolve, 100)); // Wait for 100ms @@ -334,23 +244,6 @@ export default { }; ``` -#### Cloudflare Pages - -```javascript {filename:debug-sentry.js} -export async function onRequest(context) { - await Sentry.startSpan( - { - op: "test", - name: "My First Test Transaction", - }, - async () => { - await new Promise((resolve) => setTimeout(resolve, 100)); // Wait for 100ms - throw new Error("My first Sentry error!"); - } - ); -} -``` - @@ -373,56 +266,6 @@ Server-side spans will display `0ms` for their durations. In the Cloudflare Work This is expected behavior in the Cloudflare Workers environment and affects all frameworks deployed to Cloudflare Workers, including Next.js, Astro, Remix, and others. -### Spans in `waitUntil()` - - - - - -Cloudflare's [`waitUntil()`](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/#contextwaituntil) lets work continue after the Worker returns a response. With the static trace lifecycle, Sentry snapshots the request transaction when the response is returned, so spans that finish later may be missing. - -Set `traceLifecycle: "stream"` so the SDK can send each sampled span when it finishes. Span streaming on Cloudflare requires `@sentry/cloudflare` version `10.49.0` or newer. - -Stream mode sends span records instead of assembling one transaction event with embedded spans. See Streamed Spans for filtering and migration details. - -If you need to keep the static lifecycle, use `forceTransaction: true` on the background operation instead. This records the work as a separate transaction. `forceTransaction` isn't available in stream mode. - - - - -```javascript {filename:index.js} -import * as Sentry from "@sentry/cloudflare"; - -const worker = { - async fetch(request, env, ctx) { - ctx.waitUntil( - Sentry.startSpan({ name: "background.task", op: "task" }, () => - updateCacheAndDatabase() - ) - ); - - return processRequest(request); - }, -}; - -export default Sentry.withSentry( - (env) => ({ - dsn: env.SENTRY_DSN, - tracesSampleRate: 1.0, - traceLifecycle: "stream", - }), - worker -); - -async function updateCacheAndDatabase() { - // Deferred work and any child spans are captured when they finish. -} -``` - - - - - ## Next Steps At this point, you should have integrated Sentry and should already be sending data to your Sentry project. diff --git a/docs/platforms/javascript/guides/cloudflare/install/index.mdx b/docs/platforms/javascript/guides/cloudflare/install/index.mdx new file mode 100644 index 00000000000000..2d2ddd0fc7fa3e --- /dev/null +++ b/docs/platforms/javascript/guides/cloudflare/install/index.mdx @@ -0,0 +1,23 @@ +--- +title: Installation Methods +sidebar_order: 1 +description: "Review our alternate installation methods." +--- + + + +## How To Decide Which Installation Method To Use + +How you set the SDK up depends on how your Worker is built, not on which features you want. All methods give you the same errors, traces, and options. + +### I build my Worker with Vite + +Follow the quick start, which sets Sentry up this way. This is what we recommend: the Vite plugin wraps your Worker entry at build time, so you don't write the wrapper yourself, and it instruments bundled dependencies such as database clients, which is the only way to trace them in the Workers runtime. See the Vite Plugin page for its options and what it instruments. + +### I deploy with `wrangler` directly + +Follow the Wrangler setup and wrap your entry with `Sentry.withSentry()` yourself. You keep errors and request traces, but you lose the build-time instrumentation of bundled dependencies, so spans from those packages won't appear. + +### I'm deploying a Cloudflare Pages application + +Follow Cloudflare Pages, which uses the `sentryPagesPlugin` middleware instead of a wrapper. Cloudflare recommends [moving to Workers with static assets](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/) for new projects. diff --git a/docs/platforms/javascript/guides/cloudflare/install/vite-plugin.mdx b/docs/platforms/javascript/guides/cloudflare/install/vite-plugin.mdx new file mode 100644 index 00000000000000..85d38b7644969c --- /dev/null +++ b/docs/platforms/javascript/guides/cloudflare/install/vite-plugin.mdx @@ -0,0 +1,119 @@ +--- +title: Vite Plugin +description: "Learn how to use the Sentry Cloudflare Vite plugin to instrument bundled dependencies at build time." +--- + + + + + The Sentry Cloudflare Vite plugin has **experimental** stability. + Configuration options and behavior may change or be removed in any release. + + +The Sentry Cloudflare Vite plugin (`sentryCloudflareVitePlugin`) instruments your Worker at build time. It can: + +1. **Instrument bundled dependencies**: instruments supported packages in your bundle, such as database clients and AI SDKs, giving you more traces out of the box. +2. **Auto-instrument your Worker entry**: wraps your default export with `Sentry.withSentry()`, and Durable Object, Workflow, and Agents SDK classes with the matching `instrument*WithSentry` helper at build time, so you don't need to modify your code. + +Both are opt-in while the plugin is experimental. Turn them on with [`_experimental.useDiagnosticsChannelInjection`](#_experimentalusediagnosticschannelinjection) and [`_experimental.autoInstrumentation`](#_experimentalautoinstrumentation). + +The quick start covers adding the plugin and +creating `instrument.server.ts`. This page documents what it instruments, its +options, and the details that matter once it's running. + +## Auto-instrumentation + +The plugin reads your wrangler config (probing `wrangler.json`, `wrangler.jsonc`, and `wrangler.toml` at the Vite root, or the file set with [`wranglerConfigPath`](#wranglerconfigpath)) to find the entry point, Durable Objects, workflows, and Agents SDK classes. It wraps Agents SDK classes (`Agent`, `AIChatAgent`, `McpAgent`) with `instrumentAgentWithSentry`, which also gives them automatic conversation IDs (see Cloudflare Agents SDK). + +An entry you wrapped with `withSentry` yourself is left untouched, so manual instrumentation keeps working next to the plugin. If you'd rather wrap the entry yourself, leave `_experimental.autoInstrumentation` off and follow the Wrangler setup. + +With auto-instrumentation, you can optionally provide Sentry options via a co-located `instrument.server.*` file (`.ts`, `.mts`, `.js`, `.mjs`, or `.cjs`) next to your Worker entry. The plugin resolves this location from `main` in your wrangler config. For example, if `main` is `src/worker/index.ts`, place the file at `src/worker/instrument.server.ts`, not at the project root. Use `defineCloudflareOptions` for full type-checking: + +```typescript {filename:instrument.server.ts} +import { defineCloudflareOptions } from "@sentry/cloudflare"; + +export default defineCloudflareOptions((env) => ({ + dsn: env.SENTRY_DSN, + tracesSampleRate: 1.0, +})); +``` + +If no `instrument.server.*` file exists, the SDK reads all configuration (DSN, release, environment, sample rate, etc.) from the Worker's `env` bindings at runtime. + +Configured Durable Object, Workflow, and Agents SDK classes must be declared in the Worker entry for the plugin to wrap them automatically. The plugin cannot rewrite a class that the entry only imports or re-exports from another module. In that case, wrap the imported class in the entry with its matching helper and pass it the options callback from `instrument.server.*`: + +```typescript {filename:src/worker/index.ts} +import * as Sentry from "@sentry/cloudflare"; +import sentryOptions from "./instrument.server"; +import { MyAgent as MyAgentBase } from "./my-agent"; + +export const MyAgent = Sentry.instrumentAgentWithSentry( + sentryOptions, + MyAgentBase +); +``` + +Use `instrumentDurableObjectWithSentry` for a plain Durable Object or `instrumentWorkflowWithSentry` for a Workflow. + +### Derived RPC Trace Propagation + + + +The plugin knows which bindings point at classes it wrapped itself: Durable Object bindings without a `script_name`, and service bindings naming this Worker. Those receivers are guaranteed to strip the trailing trace argument again, so the plugin adds their binding names to rpcTracePropagationBindings, which covers the calling and the receiving side alike. Traces then connect across RPC calls within one deployment, with no configuration of your own. + +Bindings to _other_ Workers stay opt-in, because their receivers may not run Sentry. List those yourself in `instrument.server.*`; whatever you list is added on top of the derived names. + +The plugin derives only the classes it wrapped itself. A class you wrapped by hand, or one re-exported from another module, runs on its own options and stays out. + +This applies to Vite builds only. At runtime a `DurableObjectNamespace` exposes no origin and a `Fetcher` does not say which service it points at, so a plain wrangler build still has to list its bindings. + +## Options + + + +Path to your wrangler config file. By default the plugin probes `wrangler.json`, `wrangler.jsonc`, and `wrangler.toml` at the Vite root. Set this when your config lives at a custom path, for example to mirror the `configPath` option of the Cloudflare Vite plugin: + +```typescript {filename:vite.config.ts} +export default defineConfig({ + plugins: [ + cloudflare({ configPath: "./wrangler.agent.jsonc" }), + sentryCloudflareVitePlugin({ + wranglerConfigPath: "./wrangler.agent.jsonc", + _experimental: { + autoInstrumentation: true, + }, + }), + ], +}); +``` + + + + + +Experimental options that may change or be removed without notice. + + + + + +Build-time instrumentation of supported dependencies. The plugin injects `diagnostics_channel.tracingChannel` calls into the bundled packages, and next to each one a snippet that registers the matching Sentry channel subscriber, which the SDK picks up in `Sentry.withSentry()`. This is how those packages get traced in the Workers runtime, where the SDK can't monkey-patch them. Both `vite build` and `vite dev` are instrumented. + +A package is only instrumented if it's actually bundled. A dependency you mark as external is resolved at runtime and never passes through the build, so it stays untraced. + + + + + +Wraps your Worker at build time so you don't have to edit your entry. The plugin reads your wrangler config, wraps the default export with `Sentry.withSentry()` (sourcing options from a co-located `instrument.server.*` file, falling back to `env`), and wraps configured classes with the matching helper: Durable Objects with `instrumentDurableObjectWithSentry`, Workflows with `instrumentWorkflowWithSentry`, and Agents SDK classes with `instrumentAgentWithSentry` (SDK version 10.69.0 or higher). Both `vite build` and `vite dev` are instrumented. Entries you wrapped yourself are left alone, so this is safe alongside manual instrumentation. The plugin also adds the bindings that resolve to the wrapped classes to `rpcTracePropagationBindings` (SDK version 10.72.0 or higher). + + + +## Migrating From Wrangler + +If you deploy with `wrangler` directly, moving to Vite is straightforward: + +1. Set up the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/get-started/) and add a `vite.config.ts` with the `cloudflare()` and `sentryCloudflareVitePlugin()` plugins as shown above. +2. Run `vite build` before `wrangler deploy`, and use `vite dev` in place of `wrangler dev` for local development. + +Your existing `wrangler.jsonc` becomes the input config, and the plugin generates the deployed output during the build. For the full list of fields that change or become redundant, see Cloudflare's [Migrating from Wrangler](https://developers.cloudflare.com/workers/vite-plugin/reference/migrating-from-wrangler-dev/) guide. diff --git a/docs/platforms/javascript/guides/cloudflare/install/wrangler.mdx b/docs/platforms/javascript/guides/cloudflare/install/wrangler.mdx new file mode 100644 index 00000000000000..4ae0a8c0fd49c5 --- /dev/null +++ b/docs/platforms/javascript/guides/cloudflare/install/wrangler.mdx @@ -0,0 +1,109 @@ +--- +title: Wrangler +description: "Learn how to instrument a Cloudflare Worker built with Wrangler, using the withSentry wrapper." +--- + + + +We recommend building your Worker with Vite and the Sentry Vite plugin. It wraps your entry for you and is the only way to trace bundled dependencies in the Workers runtime. To move an existing Wrangler project over, see Migrating From Wrangler. + + + +If you deploy with `wrangler` directly rather than building with Vite, wrap your Worker entry yourself with `Sentry.withSentry()`. + +Everything else is the same: install, Wrangler configuration, source maps, and the options reference all carry over from the quick start. + +## What You Give Up + +`withSentry` gives you the same errors and request traces as the plugin. What a plain Wrangler build can't do is instrument your bundled dependencies. + +The Workers runtime doesn't let the SDK patch modules at runtime, so packages like database and AI clients are only traced when something rewrites them during the build. That's what the Vite plugin's `_experimental.useDiagnosticsChannelInjection` does. Without it, spans from those packages are missing, and you only get the spans the SDK creates itself. + +You also have to keep the wrapper in your code, and list your RPC trace propagation bindings by hand, because a plain build can't derive them. See RPC Trace Propagation. + +## Configure + + + + + +Wrap your exported handler with `Sentry.withSentry()` to start capturing errors and traces from your Worker: + + + + +```typescript {filename:index.ts} +import * as Sentry from "@sentry/cloudflare"; + +export default Sentry.withSentry( + (env: Env) => ({ + dsn: "___PUBLIC_DSN___", + + 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, + }), + { + async fetch(request, env, ctx) { + // Your worker logic here + return new Response("Hello World!"); + }, + } +); +``` + + + + + +Durable Objects, Workflows, and Agents SDK classes each need their own wrapper. Use `instrumentDurableObjectWithSentry`, `instrumentWorkflowWithSentry`, and `instrumentAgentWithSentry`, passing the same options callback you gave `withSentry`. See Durable Objects, Workflows, and Agents SDK. + +## Verify Your Setup + + + + + +Add a `/debug-sentry` route to your Worker that throws when called: + + + + +```javascript {filename:index.js} +import * as Sentry from "@sentry/cloudflare"; + +export default Sentry.withSentry( + (env) => ({ + dsn: "___PUBLIC_DSN___", + }), + { + async fetch(request) { + const url = new URL(request.url); + + if (url.pathname === "/debug-sentry") { + throw new Error("My first Sentry error!"); + } + + // Your existing routes and logic here... + return new Response("..."); + }, + } +); +``` + + + + + +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). diff --git a/platform-includes/distributed-tracing/how-to-use/javascript.cloudflare.mdx b/platform-includes/distributed-tracing/how-to-use/javascript.cloudflare.mdx index 47d4f89bdaf8ec..7073f9ba97de67 100644 --- a/platform-includes/distributed-tracing/how-to-use/javascript.cloudflare.mdx +++ b/platform-includes/distributed-tracing/how-to-use/javascript.cloudflare.mdx @@ -11,7 +11,7 @@ By default, traces are not propagated across [RPC calls](https://developers.clou That trailing argument is why propagation is opt-in per binding: only a Sentry-instrumented receiver strips it again. List the bindings whose receiver you know runs Sentry in `rpcTracePropagationBindings` (SDK version 10.72.0 or higher). Setting the option also turns on the receiver side, so a Worker that both calls and receives needs nothing else. - If you build with the Sentry Cloudflare Vite plugin and its `autoInstrumentation` option, the plugin configures the bindings that point at classes in the same Worker. You only need to list bindings to other Workers. + If you build with the Sentry Cloudflare Vite plugin and its `autoInstrumentation` option, the plugin configures the bindings that point at classes in the same Worker. You only need to list bindings to other Workers. **Worker Side (Caller):** diff --git a/platform-includes/getting-started-config/javascript.cloudflare.mdx b/platform-includes/getting-started-config/javascript.cloudflare.mdx index 9c65668b22ddab..09f806dd40a512 100644 --- a/platform-includes/getting-started-config/javascript.cloudflare.mdx +++ b/platform-includes/getting-started-config/javascript.cloudflare.mdx @@ -10,13 +10,15 @@ Since the SDK needs access to the `AsyncLocalStorage` API, you need to set the ` ```jsonc {tabTitle:JSON} {filename:wrangler.jsonc} { - "compatibility_date": "2024-09-23", + // Set this to today's date + "compatibility_date": "{{@inject new Date().toISOString().slice(0, 10) }}", "compatibility_flags": ["nodejs_compat"], } ``` ```toml {tabTitle:Toml} {filename:wrangler.toml} -compatibility_date = "2024-09-23" +# Set this to today's date +compatibility_date = "{{@inject new Date().toISOString().slice(0, 10) }}" compatibility_flags = ["nodejs_compat"] ``` @@ -58,29 +60,3 @@ binding = "CF_VERSION_METADATA" - - - - - - - -In earlier versions, you need to manually extract `CF_VERSION_METADATA.id` and pass it as the `release` option: - - - - -```javascript -Sentry.withSentry( - (env) => ({ - dsn: "___PUBLIC_DSN___", - release: env.CF_VERSION_METADATA?.id, - }) - // ... -); -``` - - - - - diff --git a/redirects.js b/redirects.js index 86e5a71a77f41f..d29abe41fdd5cb 100644 --- a/redirects.js +++ b/redirects.js @@ -2280,6 +2280,18 @@ const userDocsRedirects = [ source: '/product/insights/:path*', destination: '/product/dashboards/sentry-dashboards/', }, + // Cloudflare setup pages moved from Features to Installation Methods. + { + source: '/platforms/javascript/guides/cloudflare/features/vite-plugin.md', + destination: + '/platforms/javascript/guides/cloudflare/install/vite-plugin.md', + }, + { + source: + '/platforms/javascript/guides/cloudflare/features/vite-plugin/:path*', + destination: + '/platforms/javascript/guides/cloudflare/install/vite-plugin/:path*', + }, // Cloudflare AI pages moved from Features to Agent Tracing. { source: '/platforms/javascript/guides/cloudflare/features/agents-sdk.md',