Skip to content

Commit d024a76

Browse files
authored
ref(nextjs): Remove all deprecated API (#10549)
1 parent b220be5 commit d024a76

37 files changed

+339
-924
lines changed

MIGRATION.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Upgrading from 7.x to 8.x
22

3+
## Removal of deprecated API in `@sentry/nextjs`
4+
5+
The following previously deprecated API has been removed from the `@sentry/nextjs` package:
6+
7+
- `withSentryApi` (Replacement: `wrapApiHandlerWithSentry`)
8+
- `withSentryAPI` (Replacement: `wrapApiHandlerWithSentry`)
9+
- `withSentryGetServerSideProps` (Replacement: `wrapGetServerSidePropsWithSentry`)
10+
- `withSentryGetStaticProps` (Replacement: `wrapGetStaticPropsWithSentry`)
11+
- `withSentryServerSideGetInitialProps` (Replacement: `wrapGetInitialPropsWithSentry`)
12+
- `withSentryServerSideAppGetInitialProps` (Replacement: `wrapAppGetInitialPropsWithSentry`)
13+
- `withSentryServerSideDocumentGetInitialProps` (Replacement: `wrapDocumentGetInitialPropsWithSentry`)
14+
- `withSentryServerSideErrorGetInitialProps` was renamed to `wrapErrorGetInitialPropsWithSentry`
15+
- `nextRouterInstrumentation` (Replaced by using `browserTracingIntegration`)
16+
- `IS_BUILD`
17+
- `isBuild`
18+
319
## Removal of Severity Enum
420

521
In v7 we deprecated the `Severity` enum in favor of using the `SeverityLevel` type. In v8 we removed the `Severity`

dev-packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,7 @@ import * as Sentry from '@sentry/nextjs';
33
import type { NextApiRequest, NextApiResponse } from 'next';
44

55
export default function handler(req: NextApiRequest, res: NextApiResponse) {
6-
// eslint-disable-next-line deprecation/deprecation
7-
const transaction = Sentry.startTransaction({ name: 'test-transaction', op: 'e2e-test' });
8-
// eslint-disable-next-line deprecation/deprecation
9-
Sentry.getCurrentScope().setSpan(transaction);
10-
11-
// eslint-disable-next-line deprecation/deprecation
12-
const span = transaction.startChild();
13-
14-
span.end();
15-
transaction.end();
6+
Sentry.startSpan({ name: 'test-span' }, span => undefined);
167

178
Sentry.flush().then(() => {
189
res.status(200).json({

packages/browser/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export {
6262
browserTracingIntegration,
6363
startBrowserTracingNavigationSpan,
6464
startBrowserTracingPageLoadSpan,
65+
DEFAULT_TRACE_PROPAGATION_TARGETS,
6566
} from '@sentry-internal/tracing';
6667
export type { RequestInstrumentationOptions } from '@sentry-internal/tracing';
6768
export {

packages/nextjs/src/client/browserTracingIntegration.ts

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,18 @@
11
import {
2-
BrowserTracing as OriginalBrowserTracing,
32
browserTracingIntegration as originalBrowserTracingIntegration,
4-
defaultRequestInstrumentationOptions,
53
startBrowserTracingNavigationSpan,
64
startBrowserTracingPageLoadSpan,
75
} from '@sentry/react';
86
import type { Integration, StartSpanOptions } from '@sentry/types';
9-
import { nextRouterInstrumentation } from '../index.client';
10-
11-
/**
12-
* A custom BrowserTracing integration for Next.js.
13-
*
14-
* @deprecated Use `browserTracingIntegration` instead.
15-
*/
16-
// eslint-disable-next-line deprecation/deprecation
17-
export class BrowserTracing extends OriginalBrowserTracing {
18-
// eslint-disable-next-line deprecation/deprecation
19-
public constructor(options?: ConstructorParameters<typeof OriginalBrowserTracing>[0]) {
20-
super({
21-
// eslint-disable-next-line deprecation/deprecation
22-
tracingOrigins:
23-
process.env.NODE_ENV === 'development'
24-
? [
25-
// Will match any URL that contains "localhost" but not "webpack.hot-update.json" - The webpack dev-server
26-
// has cors and it doesn't like extra headers when it's accessed from a different URL.
27-
// TODO(v8): Ideally we rework our tracePropagationTargets logic so this hack won't be necessary anymore (see issue #9764)
28-
/^(?=.*localhost)(?!.*webpack\.hot-update\.json).*/,
29-
/^\/(?!\/)/,
30-
]
31-
: // eslint-disable-next-line deprecation/deprecation
32-
[...defaultRequestInstrumentationOptions.tracingOrigins, /^(api\/)/],
33-
// eslint-disable-next-line deprecation/deprecation
34-
routingInstrumentation: nextRouterInstrumentation,
35-
...options,
36-
});
37-
}
38-
}
7+
import { nextRouterInstrumentation } from './routing/nextRoutingInstrumentation';
398

409
/**
4110
* A custom BrowserTracing integration for Next.js.
4211
*/
4312
export function browserTracingIntegration(
44-
options?: Parameters<typeof originalBrowserTracingIntegration>[0],
13+
options: Parameters<typeof originalBrowserTracingIntegration>[0] = {},
4514
): Integration {
4615
const browserTracingIntegrationInstance = originalBrowserTracingIntegration({
47-
// eslint-disable-next-line deprecation/deprecation
48-
tracingOrigins:
49-
process.env.NODE_ENV === 'development'
50-
? [
51-
// Will match any URL that contains "localhost" but not "webpack.hot-update.json" - The webpack dev-server
52-
// has cors and it doesn't like extra headers when it's accessed from a different URL.
53-
// TODO(v8): Ideally we rework our tracePropagationTargets logic so this hack won't be necessary anymore (see issue #9764)
54-
/^(?=.*localhost)(?!.*webpack\.hot-update\.json).*/,
55-
/^\/(?!\/)/,
56-
]
57-
: // eslint-disable-next-line deprecation/deprecation
58-
[...defaultRequestInstrumentationOptions.tracingOrigins, /^(api\/)/],
5916
...options,
6017
instrumentNavigation: false,
6118
instrumentPageLoad: false,
@@ -76,21 +33,17 @@ export function browserTracingIntegration(
7633
// tracing integration because we need to ensure the order of execution is as follows:
7734
// Instrumentation to start span on RSC fetch request runs -> Instrumentation to put tracing headers from active span on fetch runs
7835
// If it were the other way around, the RSC fetch request would not receive the tracing headers from the navigation transaction.
79-
// eslint-disable-next-line deprecation/deprecation
8036
nextRouterInstrumentation(
81-
() => undefined,
8237
false,
83-
options?.instrumentNavigation,
38+
options.instrumentNavigation === undefined ? true : options.instrumentNavigation,
8439
startPageloadCallback,
8540
startNavigationCallback,
8641
);
8742

8843
browserTracingIntegrationInstance.afterAllSetup(client);
8944

90-
// eslint-disable-next-line deprecation/deprecation
9145
nextRouterInstrumentation(
92-
() => undefined,
93-
options?.instrumentPageLoad,
46+
options.instrumentPageLoad === undefined ? true : options.instrumentPageLoad,
9447
false,
9548
startPageloadCallback,
9649
startNavigationCallback,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { defineIntegration } from '@sentry/core';
2+
import { rewriteFramesIntegration } from '@sentry/integrations';
3+
4+
export const nextjsClientStackFrameNormalizationIntegration = defineIntegration(
5+
({ assetPrefixPath }: { assetPrefixPath: string }) => {
6+
const rewriteFramesInstance = rewriteFramesIntegration({
7+
// Turn `<origin>/<path>/_next/static/...` into `app:///_next/static/...`
8+
iteratee: frame => {
9+
try {
10+
const { origin } = new URL(frame.filename as string);
11+
frame.filename = frame.filename?.replace(origin, 'app://').replace(assetPrefixPath, '');
12+
} catch (err) {
13+
// Filename wasn't a properly formed URL, so there's nothing we can do
14+
}
15+
16+
// We need to URI-decode the filename because Next.js has wildcard routes like "/users/[id].js" which show up as "/users/%5id%5.js" in Error stacktraces.
17+
// The corresponding sources that Next.js generates have proper brackets so we also need proper brackets in the frame so that source map resolving works.
18+
if (frame.filename && frame.filename.startsWith('app:///_next')) {
19+
frame.filename = decodeURI(frame.filename);
20+
}
21+
22+
if (
23+
frame.filename &&
24+
frame.filename.match(
25+
/^app:\/\/\/_next\/static\/chunks\/(main-|main-app-|polyfills-|webpack-|framework-|framework\.)[0-9a-f]+\.js$/,
26+
)
27+
) {
28+
// We don't care about these frames. It's Next.js internal code.
29+
frame.in_app = false;
30+
}
31+
32+
return frame;
33+
},
34+
});
35+
36+
return {
37+
...rewriteFramesInstance,
38+
name: 'NextjsClientStackFrameNormalization',
39+
};
40+
},
41+
);

packages/nextjs/src/client/index.ts

Lines changed: 23 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { applySdkMetadata, hasTracingEnabled } from '@sentry/core';
22
import type { BrowserOptions } from '@sentry/react';
33
import {
4-
Integrations as OriginalIntegrations,
4+
DEFAULT_TRACE_PROPAGATION_TARGETS,
55
getCurrentScope,
66
getDefaultIntegrations as getReactDefaultIntegrations,
77
init as reactInit,
@@ -11,47 +11,38 @@ import type { EventProcessor, Integration } from '@sentry/types';
1111
import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor';
1212
import { getVercelEnv } from '../common/getVercelEnv';
1313
import { browserTracingIntegration } from './browserTracingIntegration';
14-
import { BrowserTracing } from './browserTracingIntegration';
15-
import { rewriteFramesIntegration } from './rewriteFramesIntegration';
14+
import { nextjsClientStackFrameNormalizationIntegration } from './clientNormalizationIntegration';
1615
import { applyTunnelRouteOption } from './tunnelRoute';
1716

1817
export * from '@sentry/react';
19-
// eslint-disable-next-line deprecation/deprecation
20-
export { nextRouterInstrumentation } from './routing/nextRoutingInstrumentation';
18+
2119
export { captureUnderscoreErrorException } from '../common/_error';
2220

23-
/** @deprecated Import the integration function directly, e.g. `inboundFiltersIntegration()` instead of `new Integrations.InboundFilter(). */
24-
export const Integrations = {
25-
// eslint-disable-next-line deprecation/deprecation
26-
...OriginalIntegrations,
27-
BrowserTracing,
21+
const globalWithInjectedValues = global as typeof global & {
22+
__rewriteFramesAssetPrefixPath__: string;
2823
};
2924

30-
// Previously we expected users to import `BrowserTracing` like this:
31-
//
32-
// import { Integrations } from '@sentry/nextjs';
33-
// const instance = new Integrations.BrowserTracing();
34-
//
35-
// This makes the integrations unable to be treeshaken though. To address this, we now have
36-
// this individual export. We now expect users to consume BrowserTracing like so:
37-
//
38-
// import { BrowserTracing } from '@sentry/nextjs';
39-
// const instance = new BrowserTracing();
40-
// eslint-disable-next-line deprecation/deprecation
41-
export { BrowserTracing, rewriteFramesIntegration };
42-
4325
// Treeshakable guard to remove all code related to tracing
4426
declare const __SENTRY_TRACING__: boolean;
4527

4628
/** Inits the Sentry NextJS SDK on the browser with the React SDK. */
4729
export function init(options: BrowserOptions): void {
4830
const opts = {
4931
environment: getVercelEnv(true) || process.env.NODE_ENV,
32+
33+
tracePropagationTargets:
34+
process.env.NODE_ENV === 'development'
35+
? [
36+
// Will match any URL that contains "localhost" but not "webpack.hot-update.json" - The webpack dev-server
37+
// has cors and it doesn't like extra headers when it's accessed from a different URL.
38+
// TODO(v8): Ideally we rework our tracePropagationTargets logic so this hack won't be necessary anymore (see issue #9764)
39+
/^(?=.*localhost)(?!.*webpack\.hot-update\.json).*/,
40+
/^\/(?!\/)/,
41+
]
42+
: [...DEFAULT_TRACE_PROPAGATION_TARGETS, /^(api\/)/],
5043
defaultIntegrations: getDefaultIntegrations(options),
5144
...options,
52-
};
53-
54-
fixBrowserTracingIntegration(opts);
45+
} satisfies BrowserOptions;
5546

5647
applyTunnelRouteOption(opts);
5748
applySdkMetadata(opts, 'nextjs', ['nextjs', 'react']);
@@ -70,65 +61,8 @@ export function init(options: BrowserOptions): void {
7061
}
7162
}
7263

73-
// TODO v8: Remove this again
74-
// We need to handle BrowserTracing passed to `integrations` that comes from `@sentry/tracing`, not `@sentry/nextjs` :(
75-
function fixBrowserTracingIntegration(options: BrowserOptions): void {
76-
const { integrations } = options;
77-
if (!integrations) {
78-
return;
79-
}
80-
81-
if (Array.isArray(integrations)) {
82-
options.integrations = maybeUpdateBrowserTracingIntegration(integrations);
83-
} else {
84-
options.integrations = defaultIntegrations => {
85-
const userFinalIntegrations = integrations(defaultIntegrations);
86-
87-
return maybeUpdateBrowserTracingIntegration(userFinalIntegrations);
88-
};
89-
}
90-
}
91-
92-
function isNewBrowserTracingIntegration(
93-
integration: Integration,
94-
): integration is Integration & { options?: Parameters<typeof browserTracingIntegration>[0] } {
95-
// eslint-disable-next-line deprecation/deprecation
96-
return !!integration.afterAllSetup && !!(integration as BrowserTracing).options;
97-
}
98-
99-
function maybeUpdateBrowserTracingIntegration(integrations: Integration[]): Integration[] {
100-
const browserTracing = integrations.find(integration => integration.name === 'BrowserTracing');
101-
102-
if (!browserTracing) {
103-
return integrations;
104-
}
105-
106-
// If `browserTracingIntegration()` was added, we need to force-convert it to our custom one
107-
if (isNewBrowserTracingIntegration(browserTracing)) {
108-
const { options } = browserTracing;
109-
// eslint-disable-next-line deprecation/deprecation
110-
integrations[integrations.indexOf(browserTracing)] = new BrowserTracing(options);
111-
}
112-
113-
// If BrowserTracing was added, but it is not our forked version,
114-
// replace it with our forked version with the same options
115-
// eslint-disable-next-line deprecation/deprecation
116-
if (!(browserTracing instanceof BrowserTracing)) {
117-
// eslint-disable-next-line deprecation/deprecation
118-
const options: ConstructorParameters<typeof BrowserTracing>[0] = (browserTracing as BrowserTracing).options;
119-
// This option is overwritten by the custom integration
120-
delete options.routingInstrumentation;
121-
// eslint-disable-next-line deprecation/deprecation
122-
delete options.tracingOrigins;
123-
// eslint-disable-next-line deprecation/deprecation
124-
integrations[integrations.indexOf(browserTracing)] = new BrowserTracing(options);
125-
}
126-
127-
return integrations;
128-
}
129-
13064
function getDefaultIntegrations(options: BrowserOptions): Integration[] {
131-
const customDefaultIntegrations = [...getReactDefaultIntegrations(options), rewriteFramesIntegration()];
65+
const customDefaultIntegrations = getReactDefaultIntegrations(options);
13266

13367
// This evaluates to true unless __SENTRY_TRACING__ is text-replaced with "false", in which case everything inside
13468
// will get treeshaken away
@@ -138,6 +72,11 @@ function getDefaultIntegrations(options: BrowserOptions): Integration[] {
13872
}
13973
}
14074

75+
// This value is injected at build time, based on the output directory specified in the build config. Though a default
76+
// is set there, we set it here as well, just in case something has gone wrong with the injection.
77+
const assetPrefixPath = globalWithInjectedValues.__rewriteFramesAssetPrefixPath__ || '';
78+
customDefaultIntegrations.push(nextjsClientStackFrameNormalizationIntegration({ assetPrefixPath }));
79+
14180
return customDefaultIntegrations;
14281
}
14382

packages/nextjs/src/client/rewriteFramesIntegration.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)