/** @type {import('next').NextConfig} */ import { withSentryConfig } from "@sentry/nextjs/config"; import path from "path"; import { fileURLToPath } from "url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const isDev = process.env.NODE_ENV === "development"; function remotePatterns() { if (isDev) { return [ { protocol: "https", hostname: "**" }, { protocol: "http", hostname: "**" }, ]; } const cms = process.env.WAGTAIL_BASE_URL; if (!cms) { throw new Error("WAGTAIL_BASE_URL is not set, cannot derive image hosts"); } const { protocol, hostname, port } = new URL(cms); return [{ protocol: protocol.replace(":", ""), hostname, port }]; } const nextConfig = { output: "standalone", cacheComponents: true, partialPrefetching: true, // Next renders every page per request, uncached, for the crawlers and // link-preview bots on its "HTML-limited" list, so their metadata is never // streamed after . No page here streams metadata (it all comes from // cached CMS data), so no bot needs that; this pattern matches none htmlLimitedBots: /(?!)/, images: { remotePatterns: remotePatterns(), formats: ["image/avif", "image/webp"], // 90 is for editorial images (ImageFigure); AVIF at the default 75 is // visibly soft on photos. Qualities not listed here are rejected. qualities: [75, 90], minimumCacheTTL: 7 * 24 * 60 * 60, // 7 days // smoke tests build in production mode against a mock CMS on 127.0.0.1; // the flag is serialized into the build, so it must be set at build time dangerouslyAllowLocalIP: isDev || process.env.SMOKE_ALLOW_LOCAL_IMAGES === "1", }, turbopack: { root: __dirname, }, experimental: { // `typescript` is aliased to the TS6 API package (typescript-eslint can't // use TS7's native compiler yet), which has no `tsc` bin for the 16.3 CLI // checker — type-check builds through the TS6 JS API instead. `npx tsc` // (CI, manual) runs native TS7 via @typescript/native. useTypeScriptCli: false, }, }; // Errors are reported to Bugsink (bugsink.neuf.no), which speaks Sentry's // protocol. The build uploads source maps there when SENTRY_AUTH_TOKEN is // set, and removes them from the output afterwards export default withSentryConfig(nextConfig, { sentryUrl: "https://bugsink.neuf.no/", // Bugsink has no organisations; sentry-cli insists on a value org: "bugsinkhasnoorgs", project: "neuf-www", authToken: process.env.SENTRY_AUTH_TOKEN, silent: !process.env.CI, telemetry: false, sourcemaps: { deleteSourcemapsAfterUpload: true }, // the hook it asks for is for tracing navigations, which is off suppressOnRouterTransitionStartWarning: true, // Bugsink only takes errors: leave the tracing code out of the bundles bundleSizeOptimizations: { excludeDebugStatements: true, excludeTracing: true }, });