Skip to content

Commit

Permalink
feat(nextjs): Give app router prefetch requests a `http.server.prefet…
Browse files Browse the repository at this point in the history
…ch` op (#13600)

Ref (not complete fix)
#13596

This gives Next.js prefetch requests a `http.server.prefetch` op, when a
`Next-Router-Prefetch: 1` header is present.

In some situations Next.js doesn't seem to attach the header for
prefetch requests. Seems like it is only attached when the current route
is a dynamic route.
  • Loading branch information
lforst committed Sep 10, 2024
1 parent 02290d1 commit f7c033a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
2 changes: 1 addition & 1 deletion dev-packages/e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"test:prepare": "ts-node prepare.ts",
"test:validate": "run-s test:validate-configuration test:validate-test-app-setups",
"clean": "rimraf tmp node_modules pnpm-lock.yaml && yarn clean:test-applications",
"clean:test-applications": "rimraf test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml} .last-run.json && pnpm store prune"
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml} .last-run.json && pnpm store prune"
},
"devDependencies": {
"@types/glob": "8.0.0",
Expand Down
12 changes: 12 additions & 0 deletions packages/node/src/integrations/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ export const instrumentHttp = Object.assign(

isolationScope.setTransactionName(bestEffortTransactionName);

if (isKnownPrefetchRequest(req)) {
span.setAttribute('sentry.http.prefetch', true);
}

_httpOptions.instrumentation?.requestHook?.(span, req);
},
responseHook: (span, res) => {
Expand Down Expand Up @@ -275,3 +279,11 @@ function getBreadcrumbData(request: ClientRequest): Partial<SanitizedRequestData
function _isClientRequest(req: ClientRequest | HTTPModuleRequestIncomingMessage): req is ClientRequest {
return 'outputData' in req && 'outputSize' in req && !('client' in req) && !('statusCode' in req);
}

/**
* Detects if an incoming request is a prefetch request.
*/
function isKnownPrefetchRequest(req: HTTPModuleRequestIncomingMessage): boolean {
// Currently only handles Next.js prefetch requests but may check other frameworks in the future.
return req.headers['next-router-prefetch'] === '1';
}
5 changes: 5 additions & 0 deletions packages/opentelemetry/src/utils/parseSpanDescription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ export function descriptionForHttpMethod(
break;
}

// Spans for HTTP requests we have determined to be prefetch requests will have a `.prefetch` postfix in the op
if (attributes['sentry.http.prefetch']) {
opParts.push('prefetch');
}

const { urlPath, url, query, fragment, hasRoute } = getSanitizedUrl(attributes, kind);

if (!urlPath) {
Expand Down

0 comments on commit f7c033a

Please sign in to comment.