Skip to content

Commit cffb093

Browse files
committed
feat(nextjs): Trace pageloads in App Router
1 parent eec0687 commit cffb093

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

packages/nextjs/src/config/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export type NextConfigObject = {
4646
// Next.js experimental options
4747
experimental?: {
4848
instrumentationHook?: boolean;
49+
clientTraceMetadata?: string[];
4950
};
5051
};
5152

packages/nextjs/src/config/withSentryConfig.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { isThenable } from '@sentry/utils';
1+
import { isThenable, parseSemver } from '@sentry/utils';
22

3+
import * as fs from 'fs';
4+
import { sync as resolveSync } from 'resolve';
35
import type {
46
ExportedNextConfig as NextConfig,
57
NextConfigFunction,
@@ -82,6 +84,19 @@ function getFinalConfigObject(
8284
...incomingUserNextConfigObject.experimental,
8385
};
8486

87+
// Add the `clientTraceMetadata` experimental option based on Next.js version. The option got introduced in Next.js version 15.0.0 (actually 14.3.0-canary.64).
88+
// Adding the option on lower versions will cause Next.js to print nasty warnings we wouldn't confront our users with.
89+
const nextJsVersion = getNextjsVersion();
90+
if (nextJsVersion) {
91+
const { major, minor } = parseSemver(nextJsVersion);
92+
if (major && minor && (major >= 15 || (major === 14 && minor >= 3))) {
93+
incomingUserNextConfigObject.experimental = {
94+
clientTraceMetadata: ['baggage', 'sentry-trace'],
95+
...incomingUserNextConfigObject.experimental,
96+
};
97+
}
98+
}
99+
85100
return {
86101
...incomingUserNextConfigObject,
87102
webpack: constructWebpackConfigFunction(incomingUserNextConfigObject, userSentryOptions),
@@ -163,3 +178,28 @@ function setUpTunnelRewriteRules(userNextConfig: NextConfigObject, tunnelPath: s
163178
}
164179
};
165180
}
181+
182+
function getNextjsVersion(): string | undefined {
183+
const nextjsPackageJsonPath = resolveNextjsPackageJson();
184+
if (nextjsPackageJsonPath) {
185+
try {
186+
const nextjsPackageJson: { version: string } = JSON.parse(
187+
fs.readFileSync(nextjsPackageJsonPath, { encoding: 'utf-8' }),
188+
);
189+
return nextjsPackageJson.version;
190+
} catch {
191+
// noop
192+
}
193+
}
194+
195+
return undefined;
196+
}
197+
198+
function resolveNextjsPackageJson(): string | undefined {
199+
try {
200+
return resolveSync('next/package.json', { basedir: process.cwd() });
201+
} catch {
202+
// Should not happen in theory
203+
return undefined;
204+
}
205+
}

0 commit comments

Comments
 (0)