diff --git a/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts b/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts index 1cd7c40181eb..6aa0782f1233 100644 --- a/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts +++ b/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts @@ -23,7 +23,7 @@ type NextApiModule = ( } // CJS export | NextApiHandler -) & { config?: PageConfig }; +) & { config?: PageConfig & { runtime?: string } }; const userApiModule = origModule as NextApiModule; @@ -53,7 +53,13 @@ export const config = { }, }; -export default userProvidedHandler ? Sentry.withSentryAPI(userProvidedHandler, '__ROUTE__') : undefined; +const isEdgeRuntime = origConfig.runtime === 'experimental-edge'; + +export default userProvidedHandler + ? isEdgeRuntime + ? userProvidedHandler + : Sentry.withSentryAPI(userProvidedHandler, '__ROUTE__') + : undefined; // Re-export anything exported by the page module we're wrapping. When processing this code, Rollup is smart enough to // not include anything whose name matchs something we've explicitly exported above. diff --git a/packages/nextjs/src/index.client.ts b/packages/nextjs/src/index.client.ts index 2cabd92a7bcd..a28969824c92 100644 --- a/packages/nextjs/src/index.client.ts +++ b/packages/nextjs/src/index.client.ts @@ -2,6 +2,7 @@ import { RewriteFrames } from '@sentry/integrations'; import { configureScope, init as reactInit, Integrations } from '@sentry/react'; import { BrowserTracing, defaultRequestInstrumentationOptions, hasTracingEnabled } from '@sentry/tracing'; import { EventProcessor } from '@sentry/types'; +import { logger } from '@sentry/utils'; import { nextRouterInstrumentation } from './performance/client'; import { buildMetadata } from './utils/metadata'; @@ -29,10 +30,23 @@ export { BrowserTracing }; // Treeshakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean; +// This is a variable that Next.js will string replace during build with a string if run in an edge runtime from Next.js +// v12.2.1-canary.3 onwards: +// https://github.com/vercel/next.js/blob/166e5fb9b92f64c4b5d1f6560a05e2b9778c16fb/packages/next/build/webpack-config.ts#L206 +declare const EdgeRuntime: string | undefined; + type GlobalWithAssetPrefixPath = typeof global & { __rewriteFramesAssetPrefixPath__: string }; /** Inits the Sentry NextJS SDK on the browser with the React SDK. */ export function init(options: NextjsOptions): void { + if (typeof EdgeRuntime === 'string') { + // If the SDK is imported when using the Vercel Edge Runtime, it will import the browser SDK, even though it is + // running the server part of a Next.js application. We can use the `EdgeRuntime` to check for that case and make + // the init call a no-op. This will prevent the SDK from crashing on the Edge Runtime. + __DEBUG_BUILD__ && logger.log('Vercel Edge Runtime detected. Will not initialize SDK.'); + return; + } + buildMetadata(options, ['nextjs', 'react']); options.environment = options.environment || process.env.NODE_ENV; addClientIntegrations(options); diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index e64349b89c4f..993abbd4cdb8 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -22,6 +22,11 @@ export { ErrorBoundary, showReportDialog, withErrorBoundary } from '@sentry/reac type GlobalWithDistDir = typeof global & { __rewriteFramesDistDir__: string }; const domain = domainModule as typeof domainModule & { active: (domainModule.Domain & Carrier) | null }; +// This is a variable that Next.js will string replace during build with a string if run in an edge runtime from Next.js +// v12.2.1-canary.3 onwards: +// https://github.com/vercel/next.js/blob/166e5fb9b92f64c4b5d1f6560a05e2b9778c16fb/packages/next/build/webpack-config.ts#L206 +declare const EdgeRuntime: string | undefined; + // Exporting this constant means we can compute it without the linter complaining, even if we stop directly using it in // this file. It's important that it be computed as early as possible, because one of its indicators is seeing 'build' // (as in the CLI command `next build`) in `process.argv`. Later on in the build process, everything's been spun out @@ -37,6 +42,11 @@ export function init(options: NextjsOptions): void { logger.enable(); } + if (typeof EdgeRuntime === 'string') { + __DEBUG_BUILD__ && logger.log('Vercel Edge Runtime detected. Will not initialize SDK.'); + return; + } + __DEBUG_BUILD__ && logger.log('Initializing SDK...'); if (sdkAlreadyInitialized()) {