@sentry/nextjs
Version:
Official Sentry SDK for Next.js
86 lines (82 loc) • 3.12 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const core = require('@sentry/core');
const react = require('@sentry/react');
const debugBuild = require('../../common/debug-build.js');
const attributes = require('@sentry/conventions/attributes');
const op = require('@sentry/conventions/op');
const globalObject = react.WINDOW;
function extractNextDataTagInformation() {
let nextData;
const nextDataTag = globalObject.document.getElementById("__NEXT_DATA__");
if (nextDataTag?.innerHTML) {
try {
nextData = JSON.parse(nextDataTag.innerHTML);
} catch {
debugBuild.DEBUG_BUILD && core.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 = core.parseBaggageHeader(baggage);
let name = route || (core.hasSpanStreamingEnabled(client) ? core.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, "");
}
react.startBrowserTracingPageLoadSpan(
client,
{
name,
attributes: {
[attributes.SENTRY_OP]: op.PAGELOAD,
[attributes.SENTRY_ORIGIN]: "auto.pageload.nextjs.pages_router_instrumentation",
[attributes.SENTRY_SEGMENT_NAME_SOURCE]: route ? "route" : "url",
[attributes.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
);
}
exports.getNextRouteFromPathname = getNextRouteFromPathname;
exports.pagesRouterInstrumentPageLoad = pagesRouterInstrumentPageLoad;
//# sourceMappingURL=pagesRouterRoutingInstrumentation.js.map