123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- Object.defineProperty(exports, '__esModule', { value: true });
- const react = require('@sentry/react');
- const utils = require('@sentry/utils');
- const DEFAULT_TAGS = {
- 'routing.instrumentation': 'next-app-router',
- } ;
- /**
- * Instruments the Next.js Client App Router.
- */
- // TODO(v8): Clean this function up by splitting into pageload and navigation instrumentation respectively. Also remove startTransactionCb in the process.
- function appRouterInstrumentation(
- startTransactionCb,
- startTransactionOnPageLoad = true,
- startTransactionOnLocationChange = true,
- startPageloadSpanCallback,
- startNavigationSpanCallback,
- ) {
- // We keep track of the active transaction so we can finish it when we start a navigation transaction.
- let activeTransaction = undefined;
- // We keep track of the previous location name so we can set the `from` field on navigation transactions.
- // This is either a route or a pathname.
- let prevLocationName = react.WINDOW.location.pathname;
- if (startTransactionOnPageLoad) {
- const transactionContext = {
- name: prevLocationName,
- op: 'pageload',
- origin: 'auto.pageload.nextjs.app_router_instrumentation',
- tags: DEFAULT_TAGS,
- // pageload should always start at timeOrigin (and needs to be in s, not ms)
- startTimestamp: utils.browserPerformanceTimeOrigin ? utils.browserPerformanceTimeOrigin / 1000 : undefined,
- metadata: { source: 'url' },
- } ;
- activeTransaction = startTransactionCb(transactionContext);
- startPageloadSpanCallback(transactionContext);
- }
- if (startTransactionOnLocationChange) {
- utils.addFetchInstrumentationHandler(handlerData => {
- // The instrumentation handler is invoked twice - once for starting a request and once when the req finishes
- // We can use the existence of the end-timestamp to filter out "finishing"-events.
- if (handlerData.endTimestamp !== undefined) {
- return;
- }
- // Only GET requests can be navigating RSC requests
- if (handlerData.fetchData.method !== 'GET') {
- return;
- }
- const parsedNavigatingRscFetchArgs = parseNavigatingRscFetchArgs(handlerData.args);
- if (parsedNavigatingRscFetchArgs === null) {
- return;
- }
- const transactionName = parsedNavigatingRscFetchArgs.targetPathname;
- const tags = {
- ...DEFAULT_TAGS,
- from: prevLocationName,
- };
- prevLocationName = transactionName;
- if (activeTransaction) {
- activeTransaction.end();
- }
- const transactionContext = {
- name: transactionName,
- op: 'navigation',
- origin: 'auto.navigation.nextjs.app_router_instrumentation',
- tags,
- metadata: { source: 'url' },
- } ;
- startTransactionCb(transactionContext);
- startNavigationSpanCallback(transactionContext);
- });
- }
- }
- function parseNavigatingRscFetchArgs(fetchArgs)
- {
- // Make sure the first arg is a URL object
- if (!fetchArgs[0] || typeof fetchArgs[0] !== 'object' || (fetchArgs[0] ).searchParams === undefined) {
- return null;
- }
- // Make sure the second argument is some kind of fetch config obj that contains headers
- if (!fetchArgs[1] || typeof fetchArgs[1] !== 'object' || !('headers' in fetchArgs[1])) {
- return null;
- }
- try {
- const url = fetchArgs[0] ;
- const headers = fetchArgs[1].headers ;
- // Not an RSC request
- if (headers['RSC'] !== '1') {
- return null;
- }
- // Prefetch requests are not navigating RSC requests
- if (headers['Next-Router-Prefetch'] === '1') {
- return null;
- }
- return {
- targetPathname: url.pathname,
- };
- } catch (e) {
- return null;
- }
- }
- exports.appRouterInstrumentation = appRouterInstrumentation;
- //# sourceMappingURL=appRouterRoutingInstrumentation.js.map
|