Skip to content

Commit 43bbfa7

Browse files
chargomeclaude
andcommitted
feat(nextjs): Export the prerender guard for custom OpenTelemetry setups
An app that sets up OpenTelemetry itself registers its own propagator, which writes the trace meta tags of a prerendered shell. It can now register `NextSentryPropagator` and call `markPrerendersOnTracerProvider` with its tracer provider to get the same guard as the SDK's own setup. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent c015920 commit 43bbfa7

4 files changed

Lines changed: 14 additions & 3 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
- **feat(nextjs): Never emit trace meta tags from a prerender ([#25141](https://github.com/getsentry/sentry-javascript/pull/25141))**
88

9-
Apps with `cacheComponents` enabled get the `sentry-trace` and `baggage` meta tags again, so a pageload joins the trace of the server request that rendered the page. The server SDK no longer writes these tags while Next.js prerenders a page, so a cached shell never carries the trace of another visitor. This also covers ISR pages.
9+
Apps with `cacheComponents` enabled get the `sentry-trace` and `baggage` meta tags again, so a pageload joins the trace of the server request that rendered the page. The server SDK no longer writes these tags while Next.js prerenders a page, so a cached shell never carries the trace of another visitor. This also covers ISR pages. Apps that set up OpenTelemetry themselves register `NextSentryPropagator` instead of `SentryPropagator` and call `markPrerendersOnTracerProvider` with their tracer provider to get the same behaviour.
1010

1111
Work in this release was contributed by @Philip-Nwabuwa and @4ktLuffy. Thank you for your contributions!
1212

‎packages/nextjs/src/server/index.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,8 @@ export function init(options: NodeOptions): NodeClient | undefined {
239239
export * from '../common';
240240

241241
export { wrapApiHandlerWithSentry } from '../common/pages-router-instrumentation/wrapApiHandlerWithSentry';
242+
243+
// For apps that set up OpenTelemetry themselves (`enableOpenTelemetrySetup: false`), which otherwise
244+
// write the trace meta tags of a prerendered shell with the propagator they registered.
245+
export { NextSentryPropagator } from './nextSentryPropagator';
246+
export { markPrerendersOnTracerProvider } from './prerenderContext';

‎packages/nextjs/src/server/nextSentryPropagator.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { isPrerenderContext, markPrerendersOnTracerProvider } from './prerenderC
77
* A `SentryPropagator` that does not hand out the trace meta tags of a document while Next.js
88
* prerenders it. Trace context baked into a prerendered shell would be replayed to every visitor the
99
* shell is served to, so the browser could continue a trace that never handled its request.
10+
*
11+
* The SDK registers it when it sets up OpenTelemetry. An app that sets up OpenTelemetry itself
12+
* registers it in place of `SentryPropagator` and calls `markPrerendersOnTracerProvider` with its
13+
* tracer provider, which this propagator relies on to recognize a prerender.
1014
*/
1115
export class NextSentryPropagator extends SentryPropagator {
1216
/** @inheritDoc */

‎packages/nextjs/src/server/prerenderContext.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ function wrapTracer(tracer: Tracer): Tracer {
7474
const markedProviders = new WeakSet<TracerProvider>();
7575

7676
/**
77-
* Makes a tracer provider mark prerenders on the OpenTelemetry context, by wrapping the tracers it hands
78-
* out. Safe to call repeatedly with the same provider, which the per-request `init` on Cloudflare does.
77+
* Makes a tracer provider mark prerenders of Next.js on the OpenTelemetry context, by wrapping the
78+
* tracers it hands out. `NextSentryPropagator` relies on the mark. The SDK calls this for the provider it
79+
* registers; an app that sets up OpenTelemetry itself calls it with its own provider. Safe to call
80+
* repeatedly with the same provider, which the per-request `init` on Cloudflare does.
7981
*/
8082
export function markPrerendersOnTracerProvider(provider: TracerProvider): void {
8183
if (markedProviders.has(provider)) {

0 commit comments

Comments
 (0)