import type { NextConfig } from "next"; /** * Static export, served by the FastAPI app. * * The alternative — running `next start` alongside uvicorn — means a Node * runtime in the image, a second process to supervise and health-check, and a * second thing that can be down while the other is up. muse has no use for * SSR: every view is behind auth and driven by live JSON, so there is nothing * to render on a server that the client would not immediately re-render. * * So `next build` emits plain files into out/, FastAPI serves them, and the * deployment stays what it was: one container, one process, one healthcheck. * The auth middleware still guards the whole surface, because it is the same * server handing out the HTML. */ const isProd = process.env.NODE_ENV === "production"; const API = process.env.MUSE_API_ORIGIN ?? "http://127.0.0.1:5041"; const nextConfig: NextConfig = { ...(isProd ? { output: "export" as const } : {}), // No Next image optimiser without a server. Artwork already arrives from // Deezer's CDN at the size it is displayed, so there is nothing to optimise. images: { unoptimized: true }, // Dev only: `next dev` on :3000 proxies the API to the FastAPI process so // the browser sees a single origin and cookies behave as they do in prod. ...(isProd ? {} : { async rewrites() { return [ { source: "/api/:path*", destination: `${API}/api/:path*` }, { source: "/auth/:path*", destination: `${API}/auth/:path*` }, { source: "/healthz", destination: `${API}/healthz` }, ]; }, }), }; export default nextConfig;