Configuration
The shared Next.js configuration every app extends.
Every app's next.config.ts is three lines:
import { config } from '@kreogen/next-config';
export default config;config is a single shared object. Prefer createConfig(overrides), which
returns a fresh one — apps/web used to push onto config.images.remotePatterns
directly, so apps/app and apps/api silently inherited whatever it had done
to the object all three pointed at. Whether that mattered depended on module
evaluation order.
Standalone output
output: "standalone" emits a self-contained server bundle for the Docker
runtime stage.
outputFileTracingRoot is set to the workspace root, and it is not optional in
a monorepo: without it Next infers the root from the nearest lockfile, and if
that resolves to the app rather than the workspace the standalone output lands
at a path the Dockerfile does not expect.
outputFileTracingIncludes pulls in packages/database/generated, because
Prisma's client is generated to a custom output path that Next's file tracing
does not follow on its own.
Both are skipped when VERCEL is set, since Vercel builds its own output
format and warns about standalone.
External packages
serverExternalPackages: ['@prisma/client', '@aws-sdk/client-s3'],Both are Node libraries with native or dynamic requires. Bundling them into the server output either fails outright or produces something subtly broken at runtime.
Images
AVIF and WebP, with remotePatterns allowing the OAuth avatar CDNs —
lh3.googleusercontent.com and avatars.githubusercontent.com — plus the host
derived from S3_ENDPOINT when one is set.
That last one is worth knowing about. next/image refuses an unlisted host, so
without it every image uploaded through
@kreogen/storage fails to render — and the
failure looks like a broken upload rather than a missing configuration entry. A
malformed endpoint is ignored here rather than failing the build; that is the
storage package's error to report.
PostHog proxy
Rewrites that route analytics through your own origin so ad blockers do not drop them:
| Path | Proxies to |
|---|---|
/ingest/static/:path* | PostHog's static assets |
/ingest/:path* | PostHog's ingestion endpoint |
/ingest/decide | PostHog's feature flag endpoint |
skipTrailingSlashRedirect is set alongside them, because PostHog sends some
requests with a trailing slash and Next's default redirect turns those into a
307 the SDK does not follow. See
web analytics.
Other defaults
poweredByHeader: false— server identity is not something to volunteer.reactStrictMode: true.
Bundle analysis
withAnalyzer() wraps the config; see
bundle analysis.