-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathindex.ts
More file actions
130 lines (112 loc) · 5.56 KB
/
index.ts
File metadata and controls
130 lines (112 loc) · 5.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import type { Client, EventProcessor, Integration } from '@sentry/core';
import { consoleSandbox } from '@sentry/core';
import { getGlobalScope } from '@sentry/core';
import { GLOBAL_OBJ, addEventProcessor, applySdkMetadata } from '@sentry/core';
import type { BrowserOptions } from '@sentry/react';
import { getDefaultIntegrations as getReactDefaultIntegrations, init as reactInit } from '@sentry/react';
import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor';
import { getVercelEnv } from '../common/getVercelEnv';
import { isRedirectNavigationError } from '../common/nextNavigationErrorUtils';
import { browserTracingIntegration } from './browserTracingIntegration';
import { nextjsClientStackFrameNormalizationIntegration } from './clientNormalizationIntegration';
import { INCOMPLETE_APP_ROUTER_INSTRUMENTATION_TRANSACTION_NAME } from './routing/appRouterRoutingInstrumentation';
import { applyTunnelRouteOption } from './tunnelRoute';
export * from '@sentry/react';
export * from '../common';
export { captureUnderscoreErrorException } from '../common/pages-router-instrumentation/_error';
export { browserTracingIntegration } from './browserTracingIntegration';
export { captureRouterTransitionStart } from './routing/appRouterRoutingInstrumentation';
let clientIsInitialized = false;
const globalWithInjectedValues = GLOBAL_OBJ as typeof GLOBAL_OBJ & {
_sentryRewriteFramesAssetPrefixPath: string;
_sentryAssetPrefix?: string;
_sentryBasePath?: string;
_sentryRelease?: string;
_experimentalThirdPartyOriginStackFrames?: string;
};
// Treeshakable guard to remove all code related to tracing
declare const __SENTRY_TRACING__: boolean;
/** Inits the Sentry NextJS SDK on the browser with the React SDK. */
export function init(options: BrowserOptions): Client | undefined {
if (clientIsInitialized) {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.warn(
'[@sentry/nextjs] You are calling `Sentry.init()` more than once on the client. This can happen if you have both a `sentry.client.config.ts` and a `instrumentation-client.ts` file with `Sentry.init()` calls. It is recommended to call `Sentry.init()` once in `instrumentation-client.ts`.',
);
});
}
clientIsInitialized = true;
const opts = {
environment: getVercelEnv(true) || process.env.NODE_ENV,
defaultIntegrations: getDefaultIntegrations(options),
release: process.env._sentryRelease || globalWithInjectedValues._sentryRelease,
...options,
} satisfies BrowserOptions;
applyTunnelRouteOption(opts);
applySdkMetadata(opts, 'nextjs', ['nextjs', 'react']);
const client = reactInit(opts);
const filterTransactions: EventProcessor = event =>
event.type === 'transaction' && event.transaction === '/404' ? null : event;
filterTransactions.id = 'NextClient404Filter';
addEventProcessor(filterTransactions);
const filterIncompleteNavigationTransactions: EventProcessor = event =>
event.type === 'transaction' && event.transaction === INCOMPLETE_APP_ROUTER_INSTRUMENTATION_TRANSACTION_NAME
? null
: event;
filterIncompleteNavigationTransactions.id = 'IncompleteTransactionFilter';
addEventProcessor(filterIncompleteNavigationTransactions);
const filterNextRedirectError: EventProcessor = (event, hint) =>
isRedirectNavigationError(hint?.originalException) || event.exception?.values?.[0]?.value === 'NEXT_REDIRECT'
? null
: event;
filterNextRedirectError.id = 'NextRedirectErrorFilter';
addEventProcessor(filterNextRedirectError);
if (process.env.NODE_ENV === 'development') {
addEventProcessor(devErrorSymbolicationEventProcessor);
}
try {
// @ts-expect-error `process.turbopack` is a magic string that will be replaced by Next.js
if (process.turbopack) {
getGlobalScope().setTag('turbopack', true);
}
} catch (e) {
// Noop
// The statement above can throw because process is not defined on the client
}
return client;
}
function getDefaultIntegrations(options: BrowserOptions): Integration[] {
const customDefaultIntegrations = getReactDefaultIntegrations(options);
// This evaluates to true unless __SENTRY_TRACING__ is text-replaced with "false",
// in which case everything inside will get tree-shaken away
if (typeof __SENTRY_TRACING__ === 'undefined' || __SENTRY_TRACING__) {
customDefaultIntegrations.push(browserTracingIntegration());
}
// These values are injected at build time, based on the output directory specified in the build config. Though a default
// is set there, we set it here as well, just in case something has gone wrong with the injection.
const rewriteFramesAssetPrefixPath =
process.env._sentryRewriteFramesAssetPrefixPath ||
globalWithInjectedValues._sentryRewriteFramesAssetPrefixPath ||
'';
const assetPrefix = process.env._sentryAssetPrefix || globalWithInjectedValues._sentryAssetPrefix;
const basePath = process.env._sentryBasePath || globalWithInjectedValues._sentryBasePath;
const experimentalThirdPartyOriginStackFrames =
process.env._experimentalThirdPartyOriginStackFrames === 'true' ||
globalWithInjectedValues._experimentalThirdPartyOriginStackFrames === 'true';
customDefaultIntegrations.push(
nextjsClientStackFrameNormalizationIntegration({
assetPrefix,
basePath,
rewriteFramesAssetPrefixPath,
experimentalThirdPartyOriginStackFrames,
}),
);
return customDefaultIntegrations;
}
/**
* Just a passthrough in case this is imported from the client.
*/
export function withSentryConfig<T>(exportedUserNextConfig: T): T {
return exportedUserNextConfig;
}