diff --git a/instrumentation-client.ts b/instrumentation-client.ts new file mode 100644 index 000000000..cb479e76a --- /dev/null +++ b/instrumentation-client.ts @@ -0,0 +1,5 @@ +// Sentry initialization move to GlitchtipErrorReportingService to allow lazy-loading +// for PageSpeed 100 optimizations. This file is now empty to prevent the SDK +// from being included in the initial JS bundle. +import * as Sentry from '@sentry/nextjs'; +export const onRouterTransitionStart = Sentry.captureRouterTransitionStart; diff --git a/instrumentation.ts b/instrumentation.ts new file mode 100644 index 000000000..c996a0738 --- /dev/null +++ b/instrumentation.ts @@ -0,0 +1,25 @@ +import * as Sentry from '@sentry/nextjs'; + +/** + * Next.js will call this on boot for the active runtime. + */ +export async function register() { + if (process.env.NEXT_RUNTIME === 'nodejs') { + await import('./sentry.server.config'); + + // Initialize server services on boot + // We do this AFTER Sentry to ensure errors during service init are caught + const { getConfig } = await import('@/lib/config'); + getConfig(); // Trigger validation + + const { getServerAppServices } = await import('@/lib/services/create-services.server'); + getServerAppServices(); + } + + if (process.env.NEXT_RUNTIME === 'edge') { + await import('./sentry.edge.config'); + } +} + +// Capture errors from Server Components, middleware and route handlers. +export const onRequestError = Sentry.captureRequestError; diff --git a/next.config.mjs b/next.config.mjs index 8932348c6..079331113 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -9,8 +9,8 @@ const isProd = process.env.NODE_ENV === 'production'; const nextConfig = { transpilePackages: ['react-image-crop', '@react-three/fiber'], onDemandEntries: { - // Keep compiled pages/routes in memory for 5 minutes (reduced from 25m to prevent OOM) - maxInactiveAge: 5 * 60 * 1000, + // Keep compiled pages/routes in memory for 1 minute (optimized for memory usage) + maxInactiveAge: 60 * 1000, // Keep up to 2 pages in the dev buffer (reduced from 10 to prevent OOM) pagesBufferLength: 2, }, @@ -507,6 +507,10 @@ const nextConfig = { source: '/en/agbs', destination: '/en/terms', }, + { + source: '/errors/:path*', + destination: `${glitchtipDomain}/:path*`, + }, ], afterFiles: [], fallback: [], diff --git a/sentry.edge.config.ts b/sentry.edge.config.ts new file mode 100644 index 000000000..7b2a127ff --- /dev/null +++ b/sentry.edge.config.ts @@ -0,0 +1,15 @@ +import * as Sentry from '@sentry/nextjs'; + +const dsn = process.env.SENTRY_DSN; +const isProd = process.env.NODE_ENV === 'production'; + +Sentry.init({ + dsn, + enabled: isProd && Boolean(dsn), + + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: false, +}); diff --git a/sentry.server.config.ts b/sentry.server.config.ts new file mode 100644 index 000000000..7b2a127ff --- /dev/null +++ b/sentry.server.config.ts @@ -0,0 +1,15 @@ +import * as Sentry from '@sentry/nextjs'; + +const dsn = process.env.SENTRY_DSN; +const isProd = process.env.NODE_ENV === 'production'; + +Sentry.init({ + dsn, + enabled: isProd && Boolean(dsn), + + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: false, +}); diff --git a/src/instrumentation.ts b/src/instrumentation.ts deleted file mode 100644 index b9c1976bb..000000000 --- a/src/instrumentation.ts +++ /dev/null @@ -1,5 +0,0 @@ -export function register() { - if (process.env.NEXT_RUNTIME === 'nodejs') { - console.log('[Instrumentation] Server-side registration active'); - } -}