Ctrl K
ComunidadGuías…

next.config.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * next.config.ts
 *
 * Next.js framework configuration. Kept minimal on purpose - security headers live in
 * `proxy.ts` (Next 16's per-request hook, formerly `middleware.ts`) so they apply
 * per-request with a per-request CSP nonce, not as statically-baked `headers()`
 * entries.
 *
 * Reasoning: a static CSP would force `'unsafe-inline'` for scripts (because Next's
 * hydration data is inline), which defeats most of the value of CSP. The proxy
 * approach issues a fresh nonce on every request and threads it through to Next's
 * inline scripts via the `nonce` mechanism Next supports natively.
 */

import type { NextConfig } from "next";

const config: NextConfig = {
  // Next 16 removed the built-in ESLint integration (`next lint`), so there's
  // no `eslint` config key anymore - linting runs only via `npm run lint`.

  // `npm run typecheck` runs as a separate CI step.
  // We pay for one type-check pass, not two.
  typescript: { ignoreBuildErrors: false },

  // React strict mode catches double-renders and effect lifecycle bugs in development.
  reactStrictMode: true,

  // Disable the `X-Powered-By: Next.js` header - no fingerprinting our stack to attackers.
  poweredByHeader: false,

  // Use the standalone output for the Docker image - produces a minimal `server.js`
  // and a focused `node_modules` tree, ~80% smaller than full output.
  output: "standalone",

  // Disable Next's built-in image optimizer at runtime: the wordmark PNGs in
  // /public are tiny pre-sized assets (no resizing or format conversion
  // needed), and operator-uploaded brand logos render via a plain <img> in
  // BrandMark. With this on, `<Image>` tags still work - they just serve
  // the file at its intrinsic size - and the outputFileTracingExcludes
  // below keeps the ~16 MB of @img/sharp prebuilt binaries out of the
  // standalone bundle entirely.
  images: { unoptimized: true },

  // Explicit trace exclusions for packages that Next.js statically follows
  // into the standalone bundle but that we don't actually invoke at
  // runtime in production:
  //
  //   • @img/sharp* (16 MB) - optionalDep of `next`, only used by
  //     `images.unoptimized: false`. Disabled above; this drops the
  //     binaries from the runner.
  //
  // jsdom (~8 MB) is intentionally NOT excluded here: it's used at
  // runtime by `isomorphic-dompurify` in `lib/security/svg.ts` to
  // sanitize operator-uploaded SVG logos. A future swap to a lighter
  // DOM (linkedom failed compatibility testing; xmldom + custom
  // sanitizer is the candidate path) would let us add jsdom to this
  // list and shed another ~8 MB.
  outputFileTracingExcludes: {
    "*": ["node_modules/@img/**", "node_modules/sharp/**"],
  },

  // External packages that should not be bundled by the server build (native bindings,
  // dynamic `require('fs'|'path')`, optional deps). Drizzle's pg driver is the classic
  // case; better-sqlite3 ships a `.node` binding via `bindings` (which itself requires
  // `fs`/`path`); pg pulls `pgpass` + `pg-connection-string` which both touch `fs`/`path`.
  // Leaving them external keeps webpack out of their internals and lets the runtime
  // `require` them as plain Node modules from `./node_modules`.
  //
  // Note: this list does NOT apply to `instrumentation.ts` (Next 15 limitation -
  // tracked at vercel/next.js#53523), which is why we don't put runtime DB checks in
  // that file. The migrate script's own incomplete-migrations guard is the equivalent
  // safety net.
  serverExternalPackages: [
    "pg",
    "pg-connection-string",
    "pgpass",
    "better-sqlite3",
    "bindings",
    "file-uri-to-path",
    "pino",
    "pino-pretty",
    "undici",
    "echarts",
  ],

  experimental: {
    // Tighter inline-script CSP via per-request nonces. Required for `middleware.ts` to thread
    // the nonce into Next's framework scripts.
    // See: https://nextjs.org/docs/app/building-your-application/configuring/content-security-policy

    // Disable Next's client-side router cache for dynamic RSC payloads.
    // Without this, navigating between tabs (zone Records → Change history → back)
    // serves a cached RSC payload for up to 30 s - making the page look frozen and
    // hiding the loading shimmer. PDNS state can change between tab switches; we
    // want a live fetch every time.
    //
    // We only override `dynamic`; `static` is left at Next's default. Next 16
    // clamps `staleTimes.static` to a minimum of 30 s and silently ignores a
    // lower value (the old `static: 0` was a no-op), so leaving the key out is
    // honest about what actually takes effect. Prefetched static RSC payloads
    // keep caching, so plain link prefetching still works.
    staleTimes: {
      dynamic: 0,
    },
  },
};

export default config;