import path from 'node:path'; import { config as loadEnv } from 'dotenv'; import { withSentryConfig } from '@sentry/nextjs'; import type { NextConfig } from 'next'; // The monorepo keeps one .env at the root; Next only looks in the app directory. // In a container the file does not exist and the platform supplies the // environment instead — dotenv never overwrites an already-set variable, so // this line is a no-op there rather than a conflict. loadEnv({ path: '../../.env' }); const config: NextConfig = { reactStrictMode: true, /** * Traces the server build and its used dependencies into * `.next/standalone`, so the runtime image carries a node_modules with only * what actually runs. Without it a Docker image for this monorepo has to ship * every workspace's dev dependencies — drizzle-kit, vitest, eslint, the whole * toolchain — to start one server. * * `outputFileTracingRoot` must point at the REPO root, not the app: pnpm * hoists to a root `node_modules/.pnpm` store, and tracing from apps/web * silently omits every symlinked workspace package. */ output: 'standalone', outputFileTracingRoot: path.join(__dirname, '../..'), // The workspace packages ship TypeScript source, not build output. transpilePackages: ['@linkdr/api', '@linkdr/db', '@linkdr/shared', '@linkdr/storage'], images: { remotePatterns: [ // Where everything is served from once `pnpm assets:migrate` has run. { protocol: 'https', hostname: '**.digitaloceanspaces.com' }, { protocol: 'https', hostname: '**.cdn.digitaloceanspaces.com' }, // The seed writes source urls and the migration rewrites them, so a // freshly seeded environment points here until that job has run. { protocol: 'https', hostname: 'images.unsplash.com' }, ], }, // postgres-js opens raw sockets; it must not be bundled into the server chunk. serverExternalPackages: ['postgres'], }; /** * Bugsink speaks the Sentry protocol, so the Sentry build plugin applies — but * only the parts that make sense for a self-hosted error tracker. * * Source maps are uploaded so a minified production stack is readable, and then * deleted from the build output so they are not served publicly. Everything * tracing-related stays off: Bugsink does not ingest it. */ export default withSentryConfig(config, { // Bugsink has no organisation/project slugs in the Sentry sense; the DSN // carries the project. These are only used by the upload step, which is // skipped entirely without an auth token. silent: true, disableLogger: true, sourcemaps: { deleteSourcemapsAfterUpload: true, }, // Do NOT route events through a Next rewrite: the tunnel exists to dodge ad // blockers against sentry.io, and this DSN is our own host already. tunnelRoute: undefined, // The SDK's automatic Vercel Cron instrumentation has nothing to talk to here. automaticVercelMonitors: false, });