diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetching/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetching/page.tsx
new file mode 100644
index 000000000000..4cb811ecf1b4
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetching/page.tsx
@@ -0,0 +1,9 @@
+import Link from 'next/link';
+
+export default function Page() {
+ return (
+
+ link
+
+ );
+}
diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetching/to-be-prefetched/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetching/to-be-prefetched/page.tsx
new file mode 100644
index 000000000000..83aac90d65cf
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetching/to-be-prefetched/page.tsx
@@ -0,0 +1,5 @@
+export const dynamic = 'force-dynamic';
+
+export default function Page() {
+ return
Hello
;
+}
diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts
index 40c3d68096c2..1b3be0840f3f 100644
--- a/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts
+++ b/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts
@@ -2,4 +2,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/package.json b/dev-packages/e2e-tests/test-applications/nextjs-15/package.json
index 66b38e2e5cc0..a79d34746ee4 100644
--- a/dev-packages/e2e-tests/test-applications/nextjs-15/package.json
+++ b/dev-packages/e2e-tests/test-applications/nextjs-15/package.json
@@ -18,7 +18,7 @@
"@types/node": "^18.19.1",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",
- "next": "15.0.0-canary.182",
+ "next": "15.3.0-canary.33",
"react": "beta",
"react-dom": "beta",
"typescript": "~5.0.0"
diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-spans.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-spans.test.ts
new file mode 100644
index 000000000000..b59a45f31f8b
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-spans.test.ts
@@ -0,0 +1,24 @@
+import { expect, test } from '@playwright/test';
+import { waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Prefetch client spans should have a http.request.prefetch attribute', async ({ page }) => {
+ test.skip(process.env.TEST_ENV === 'development', "Prefetch requests don't have the prefetch header in dev mode");
+
+ const pageloadTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => {
+ return transactionEvent?.transaction === '/prefetching';
+ });
+
+ await page.goto(`/prefetching`);
+
+ // Make it more likely that nextjs prefetches
+ await page.hover('#prefetch-link');
+
+ expect((await pageloadTransactionPromise).spans).toContainEqual(
+ expect.objectContaining({
+ op: 'http.client',
+ data: expect.objectContaining({
+ 'http.request.prefetch': true,
+ }),
+ }),
+ );
+});
diff --git a/packages/nextjs/src/client/browserTracingIntegration.ts b/packages/nextjs/src/client/browserTracingIntegration.ts
index 53cb3e4f6a3f..ab9ee6c43748 100644
--- a/packages/nextjs/src/client/browserTracingIntegration.ts
+++ b/packages/nextjs/src/client/browserTracingIntegration.ts
@@ -12,6 +12,16 @@ export function browserTracingIntegration(
...options,
instrumentNavigation: false,
instrumentPageLoad: false,
+ onRequestSpanStart(...args) {
+ const [span, { headers }] = args;
+
+ // Next.js prefetch requests have a `next-router-prefetch` header
+ if (headers?.get('next-router-prefetch')) {
+ span?.setAttribute('http.request.prefetch', true);
+ }
+
+ return options.onRequestSpanStart?.(...args);
+ },
});
const { instrumentPageLoad = true, instrumentNavigation = true } = options;