Skip to content

Commit 4d0c270

Browse files
lforstLms24
andauthored
feat(nextjs): Mark clientside prefetch request spans with http.request.prefetch: true attribute (#15980)
Adds a `http.request.prefetch: true` attribute to Next.js clientside requests if they're prefetching other pages. --------- Co-authored-by: Lukas Stracke <lukas.stracke@sentry.io>
1 parent 186e696 commit 4d0c270

File tree

6 files changed

+50
-2
lines changed

6 files changed

+50
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Link from 'next/link';
2+
3+
export default function Page() {
4+
return (
5+
<Link id="prefetch-link" href="/prefetching/to-be-prefetched">
6+
link
7+
</Link>
8+
);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const dynamic = 'force-dynamic';
2+
3+
export default function Page() {
4+
return <p>Hello</p>;
5+
}

dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
/// <reference types="next/image-types/global" />
33

44
// NOTE: This file should not be edited
5-
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
5+
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

dev-packages/e2e-tests/test-applications/nextjs-15/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@types/node": "^18.19.1",
1919
"@types/react": "18.0.26",
2020
"@types/react-dom": "18.0.9",
21-
"next": "15.0.0-canary.182",
21+
"next": "15.3.0-canary.33",
2222
"react": "beta",
2323
"react-dom": "beta",
2424
"typescript": "~5.0.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForTransaction } from '@sentry-internal/test-utils';
3+
4+
test('Prefetch client spans should have a http.request.prefetch attribute', async ({ page }) => {
5+
test.skip(process.env.TEST_ENV === 'development', "Prefetch requests don't have the prefetch header in dev mode");
6+
7+
const pageloadTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => {
8+
return transactionEvent?.transaction === '/prefetching';
9+
});
10+
11+
await page.goto(`/prefetching`);
12+
13+
// Make it more likely that nextjs prefetches
14+
await page.hover('#prefetch-link');
15+
16+
expect((await pageloadTransactionPromise).spans).toContainEqual(
17+
expect.objectContaining({
18+
op: 'http.client',
19+
data: expect.objectContaining({
20+
'http.request.prefetch': true,
21+
}),
22+
}),
23+
);
24+
});

packages/nextjs/src/client/browserTracingIntegration.ts

+10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ export function browserTracingIntegration(
1212
...options,
1313
instrumentNavigation: false,
1414
instrumentPageLoad: false,
15+
onRequestSpanStart(...args) {
16+
const [span, { headers }] = args;
17+
18+
// Next.js prefetch requests have a `next-router-prefetch` header
19+
if (headers?.get('next-router-prefetch')) {
20+
span?.setAttribute('http.request.prefetch', true);
21+
}
22+
23+
return options.onRequestSpanStart?.(...args);
24+
},
1525
});
1626

1727
const { instrumentPageLoad = true, instrumentNavigation = true } = options;

0 commit comments

Comments
 (0)