import type { NextConfig } from "next"; const apiUrl = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:5228"; // Content-Security-Policy moved to src/middleware.ts — it needs a fresh random nonce per request (so // script-src can drop 'unsafe-inline'/'unsafe-eval'), which a static header list here can't produce. const securityHeaders = [ { key: "X-Frame-Options", value: "DENY" }, { key: "X-Content-Type-Options", value: "nosniff" }, { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" }, // The API sets HSTS for /api when PHONIX_FORCE_HTTPS is on, but Next serves everything else — the // storefront, the whole admin panel, and the login form the session cookie is issued from. Without it here // a first visit over http:// (a typed domain, an old bookmark, a hostile network answering :80) is // strippable, and the browser has no standing instruction to refuse. Two years with subdomains, and // preload-eligible. Browsers ignore this header on plain http, so local development is unaffected. { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" }, ]; const nextConfig: NextConfig = { // Emit a self-contained server bundle (.next/standalone) so the Docker runtime image stays small. output: "standalone", async headers() { return [{ source: "/:path*", headers: securityHeaders }]; }, // Same-origin /api/* (e.g. the relative image URLs the API returns, like /api/upload/{id}) is forwarded to // the backend. In production the reverse proxy routes /api straight to the API before Next sees it, so this // is inert there; it only bridges split-port local dev where the frontend and API run on different ports. // Client JS already calls the API on its absolute origin, so those requests don't pass through this rewrite. async rewrites() { return [{ source: "/api/:path*", destination: `${apiUrl}/api/:path*` }]; }, // The products section moved from /films to /products. Keep the old paths working so existing links, // bookmarks, and any hrefs still stored as /films (e.g. home categories) don't 404. async redirects() { return [ { source: "/films", destination: "/products", permanent: true }, { source: "/films/:path*", destination: "/products/:path*", permanent: true }, // Legacy product URLs: /products/detail?id=N → /products/N, which the // [slug] page then 308s to the full canonical slug. { source: "/products/detail", has: [{ type: "query", key: "id", value: "(?\\d+)" }], destination: "/products/:id", permanent: true, }, { source: "/products/detail", destination: "/products", permanent: true }, ]; }, }; export default nextConfig;