UNPKG

@sentry/nextjs

Version:
83 lines (80 loc) • 3.06 kB
import { parseBaggageHeader, hasSpanStreamingEnabled, PAGELOAD_SPAN_NAME_FALLBACK, debug } from '@sentry/core'; import { WINDOW, startBrowserTracingPageLoadSpan } from '@sentry/react'; import { DEBUG_BUILD } from '../../common/debug-build.js'; import { URL_TEMPLATE, SENTRY_SEGMENT_NAME_SOURCE, SENTRY_ORIGIN, SENTRY_OP } from '@sentry/conventions/attributes'; import { PAGELOAD } from '@sentry/conventions/op'; const globalObject = WINDOW; function extractNextDataTagInformation() { let nextData; const nextDataTag = globalObject.document.getElementById("__NEXT_DATA__"); if (nextDataTag?.innerHTML) { try { nextData = JSON.parse(nextDataTag.innerHTML); } catch { DEBUG_BUILD && debug.warn("Could not extract __NEXT_DATA__"); } } if (!nextData) { return {}; } const nextDataTagInfo = {}; const { page, query, props } = nextData; nextDataTagInfo.route = page; nextDataTagInfo.params = query; if (props?.pageProps) { nextDataTagInfo.sentryTrace = props.pageProps._sentryTraceData; nextDataTagInfo.baggage = props.pageProps._sentryBaggage; } return nextDataTagInfo; } function pagesRouterInstrumentPageLoad(client) { const { route, params, sentryTrace, baggage } = extractNextDataTagInformation(); const parsedBaggage = parseBaggageHeader(baggage); let name = route || (hasSpanStreamingEnabled(client) ? PAGELOAD_SPAN_NAME_FALLBACK : globalObject.location.pathname); if (parsedBaggage?.["sentry-transaction"] && name === "/_error") { name = parsedBaggage["sentry-transaction"]; name = name.replace(/^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS|TRACE|CONNECT)\s+/i, ""); } startBrowserTracingPageLoadSpan( client, { name, attributes: { [SENTRY_OP]: PAGELOAD, [SENTRY_ORIGIN]: "auto.pageload.nextjs.pages_router_instrumentation", [SENTRY_SEGMENT_NAME_SOURCE]: route ? "route" : "url", [URL_TEMPLATE]: route, ...params && { ...params } } }, { sentryTrace, baggage } ); } function getNextRouteFromPathname(pathname) { const pageRoutes = globalObject.__BUILD_MANIFEST?.sortedPages; if (!pageRoutes) { return; } return pageRoutes.find((route) => { const routeRegExp = convertNextRouteToRegExp(route); return pathname.match(routeRegExp); }); } function convertNextRouteToRegExp(route) { const routeParts = route.split("/"); let optionalCatchallWildcardRegex = ""; if (routeParts[routeParts.length - 1]?.match(/^\[\[\.\.\..+\]\]$/)) { routeParts.pop(); optionalCatchallWildcardRegex = "(?:/(.+?))?"; } const rejoinedRouteParts = routeParts.map( (routePart) => routePart.replace(/^\[\.\.\..+\]$/, "(.+?)").replace(/^\[.*\]$/, "([^/]+?)") // Replace route wildcards with lazy regex wildcards ).join("/"); return new RegExp( `^${rejoinedRouteParts}${optionalCatchallWildcardRegex}(?:/)?$` // optional slash at the end ); } export { getNextRouteFromPathname, pagesRouterInstrumentPageLoad }; //# sourceMappingURL=pagesRouterRoutingInstrumentation.js.map