Files
klz-cables.com/.pnpm-store/v10/files/a4/5164160d556ea467c7e240ad60d7fd6b64fca0ff4c9233188c8e6253606e0fca2eb985f39a37682f2ff1416918676a76f78d92d3f60cbcbb57206461e38c84
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

135 lines
5.7 KiB
Plaintext

Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const browser = require('@sentry/browser');
const core = require('@sentry/core');
/**
* A custom browser tracing integration for TanStack Router.
*
* The minimum compatible version of `@tanstack/react-router` is `1.64.0`.
*
* @param router A TanStack Router `Router` instance that should be used for routing instrumentation.
* @param options Sentry browser tracing configuration.
*/
function tanstackRouterBrowserTracingIntegration(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
router, // This is `any` because we don't want any type mismatches if TanStack Router changes their types
options = {},
) {
const castRouterInstance = router;
const browserTracingIntegrationInstance = browser.browserTracingIntegration({
...options,
instrumentNavigation: false,
instrumentPageLoad: false,
});
const { instrumentPageLoad = true, instrumentNavigation = true } = options;
return {
...browserTracingIntegrationInstance,
afterAllSetup(client) {
browserTracingIntegrationInstance.afterAllSetup(client);
const initialWindowLocation = browser.WINDOW.location;
if (instrumentPageLoad && initialWindowLocation) {
const matchedRoutes = castRouterInstance.matchRoutes(
initialWindowLocation.pathname,
castRouterInstance.options.parseSearch(initialWindowLocation.search),
{ preload: false, throwOnError: false },
);
const lastMatch = matchedRoutes[matchedRoutes.length - 1];
// If we only match __root__, we ended up not matching any route at all, so
// we fall back to the pathname.
const routeMatch = lastMatch?.routeId !== '__root__' ? lastMatch : undefined;
browser.startBrowserTracingPageLoadSpan(client, {
name: routeMatch ? routeMatch.routeId : initialWindowLocation.pathname,
attributes: {
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react.tanstack_router',
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: routeMatch ? 'route' : 'url',
...routeMatchToParamSpanAttributes(routeMatch),
},
});
}
if (instrumentNavigation) {
// The onBeforeNavigate hook is called at the very beginning of a navigation and is only called once per navigation, even when the user is redirected
castRouterInstance.subscribe('onBeforeNavigate', onBeforeNavigateArgs => {
// onBeforeNavigate is called during pageloads. We can avoid creating navigation spans by:
// 1. Checking if there's no fromLocation (initial pageload)
// 2. Comparing the states of the to and from arguments
if (
!onBeforeNavigateArgs.fromLocation ||
onBeforeNavigateArgs.toLocation.state === onBeforeNavigateArgs.fromLocation.state
) {
return;
}
const matchedRoutesOnBeforeNavigate = castRouterInstance.matchRoutes(
onBeforeNavigateArgs.toLocation.pathname,
onBeforeNavigateArgs.toLocation.search,
{ preload: false, throwOnError: false },
);
const onBeforeNavigateLastMatch = matchedRoutesOnBeforeNavigate[matchedRoutesOnBeforeNavigate.length - 1];
const onBeforeNavigateRouteMatch =
onBeforeNavigateLastMatch?.routeId !== '__root__' ? onBeforeNavigateLastMatch : undefined;
const navigationLocation = browser.WINDOW.location;
const navigationSpan = browser.startBrowserTracingNavigationSpan(client, {
name: onBeforeNavigateRouteMatch ? onBeforeNavigateRouteMatch.routeId : navigationLocation.pathname,
attributes: {
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.tanstack_router',
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: onBeforeNavigateRouteMatch ? 'route' : 'url',
},
});
// In case the user is redirected during navigation we want to update the span with the right value.
const unsubscribeOnResolved = castRouterInstance.subscribe('onResolved', onResolvedArgs => {
unsubscribeOnResolved();
if (navigationSpan) {
const matchedRoutesOnResolved = castRouterInstance.matchRoutes(
onResolvedArgs.toLocation.pathname,
onResolvedArgs.toLocation.search,
{ preload: false, throwOnError: false },
);
const onResolvedLastMatch = matchedRoutesOnResolved[matchedRoutesOnResolved.length - 1];
const onResolvedRouteMatch =
onResolvedLastMatch?.routeId !== '__root__' ? onResolvedLastMatch : undefined;
if (onResolvedRouteMatch) {
navigationSpan.updateName(onResolvedRouteMatch.routeId);
navigationSpan.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
navigationSpan.setAttributes(routeMatchToParamSpanAttributes(onResolvedRouteMatch));
}
}
});
});
}
},
};
}
function routeMatchToParamSpanAttributes(match) {
if (!match) {
return {};
}
const paramAttributes = {};
Object.entries(match.params).forEach(([key, value]) => {
paramAttributes[`url.path.params.${key}`] = value; // TODO(v11): remove attribute which does not adhere to Sentry's semantic convention
paramAttributes[`url.path.parameter.${key}`] = value;
paramAttributes[`params.${key}`] = value; // params.[key] is an alias
});
return paramAttributes;
}
exports.tanstackRouterBrowserTracingIntegration = tanstackRouterBrowserTracingIntegration;
//# sourceMappingURL=tanstackrouter.js.map