Skip to content

feat(nextjs): Add @sentry/nextjs/cloudflare - #24998

Draft
JPeer264 wants to merge 1 commit into
jp/nextjs-move-server-span-hooksfrom
jp/nextjs-cloudflare-entry
Draft

JPeer264 wants to merge 1 commit into
jp/nextjs-move-server-span-hooksfrom
jp/nextjs-cloudflare-entry

Conversation

@JPeer264

@JPeer264 JPeer264 commented Oct 2, 2026

Copy link
Copy Markdown
Member

Adds withSentry from @sentry/nextjs/cloudflare for the Worker entry of a Next.js app on Cloudflare Workers, for example .open-next/worker.js of OpenNext or the fetch handler of vinext. It is withSentry of @sentry/cloudflare with the Next.js handling of the server init added, so a Next.js app on Workers gets the spans it gets on Node.js from one wrapper, without new options. This is the only new public API.

Decisions:

  • It installs the OpenTelemetry async context strategy at module load. The AsyncLocalStorage strategy of @sentry/cloudflare loses the OpenTelemetry context of the Next.js spans, so their parents and context values break.
  • The request spans of Next.js (BaseServer.handleRequest) are ignored, so the request span of withSentry is the only http.server span. Next.js then writes the route and status onto it, and its other spans become its children.
  • From compatibility_date 2026-02-19, process.cwd() is /bundle during a request. Next.js then misses its router server context and extracts the incoming trace again. The propagator keeps the request span as parent in that case, else each continued request has two segments.
  • sentry.server.config.ts and sentry.edge.config.ts still run in the Worker but create no client there. They hand over the build release of withSentryConfig, which only code that Next.js compiles can read.
  • @sentry/cloudflare becomes a dependency of @sentry/nextjs. Its only new transitive dependency is magic-string.

Known limit: with traceLifecycle: 'static', the request span keeps its URL name, because ignored spans stay inactive only with span streaming.

The nextjs-16-cf-workers e2e app now uses it, which un-skips its server tests and adds tests for D1 spans, the OpenTelemetry context and trace continuation.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 29.52 kB - -
@sentry/browser - with treeshaking flags 27.68 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.57 kB - -
@sentry/browser (incl. Tracing) 51.45 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 51.46 kB - -
@sentry/browser (incl. Tracing, Profiling) 54.46 kB - -
@sentry/browser (incl. Tracing, Replay) 91.04 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 80.03 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 95.74 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 108.71 kB - -
@sentry/browser (incl. Feedback) 47.04 kB - -
@sentry/browser (incl. sendFeedback) 34.57 kB - -
@sentry/browser (incl. FeedbackAsync) 39.68 kB - -
@sentry/browser (incl. Metrics) 30.54 kB - -
@sentry/browser (incl. Logs) 30.82 kB - -
@sentry/browser (incl. Metrics & Logs) 31.48 kB - -
@sentry/react 31.36 kB - -
@sentry/react (incl. Tracing) 53.8 kB - -
@sentry/vue 37.51 kB - -
@sentry/vue (incl. Tracing) 54.33 kB - -
@sentry/svelte 29.55 kB - -
@sentry/remix (Remix 3 client bundle) 55.77 kB - -
CDN Bundle 31.22 kB - -
CDN Bundle (incl. Tracing) 51.98 kB - -
CDN Bundle (incl. Logs, Metrics) 33.46 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 53.91 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 74.2 kB - -
CDN Bundle (incl. Tracing, Replay) 89.56 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 91.53 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 95.72 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 97.71 kB - -
CDN Bundle - uncompressed 92.14 kB - -
CDN Bundle (incl. Tracing) - uncompressed 154.49 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 98.71 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 160.45 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 228.28 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 274.22 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 280.16 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 287.93 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 293.86 kB - -
@sentry/nextjs (client) 56.32 kB - -
@sentry/sveltekit (client) 51.87 kB - -
@sentry/core/server 40.59 kB - -
@sentry/core/browser 13.63 kB - -
@sentry/node 144.69 kB +0.01% +11 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 83.2 kB - -
@sentry/node - without tracing 93.24 kB +0.02% +10 B 🔺
@sentry/node - without channel injection 122.95 kB +0.01% +8 B 🔺
@sentry/aws-serverless 101.51 kB +0.01% +4 B 🔺
@sentry/cloudflare (withSentry) - minified 208.72 kB +0.06% +106 B 🔺
@sentry/cloudflare (withSentry) 518.61 kB +0.08% +401 B 🔺

View base workflow run

`withSentry` from `@sentry/nextjs/cloudflare` wraps the Worker entry of a
Next.js app on Cloudflare Workers, e.g. `.open-next/worker.js` of OpenNext or
the fetch handler of vinext. It is `withSentry` of `@sentry/cloudflare` with
the Next.js handling added:

- It installs the OpenTelemetry async context strategy and context manager
  at module load, so the spans of Next.js nest and keep their OpenTelemetry
  context as on Node.js.
- Its client gets the span hooks and `ignoreSpans` of the server `init`, the
  `use cache` integration, the Sentry propagator and the Next.js SDK
  metadata.
- The propagator keeps the request span as parent when Next.js extracts an
  incoming trace that the root span already continued. Next.js does this
  when it misses its router server context, e.g. on Workers where
  `process.cwd()` is `/bundle`, and each continued request then had two
  segments.
- The request spans of Next.js (`BaseServer.handleRequest`) are ignored,
  so the request span of `withSentry` is the only `http.server` span. Next.js
  writes the route and status onto it, and the other Next.js spans become
  its children.
- Requests to the tunnel route are not sampled.
- The server and edge `init` in `sentry.*.config.ts` create no client in the
  Worker. They hand over the build release of `withSentryConfig`, which only
  code that Next.js compiles can read.

The request root span of `@sentry/cloudflare` gets the route name of Next.js
at span end, and middleware no longer renames a root span that Next.js did
not start.

The `nextjs-16-cf-workers` e2e app now uses it. This runs the server tests
that were skipped, and adds tests for D1 spans, the OpenTelemetry context and
trace continuation. Its `compatibility_date` moves to 2026-02-19, the first
date on which Next.js extracts the incoming trace again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JPeer264
JPeer264 force-pushed the jp/nextjs-cloudflare-entry branch from 2ac09b0 to fb54ebb Compare October 2, 2026 18:33

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant