import type { NextConfig } from "next"; import { existsSync } from "node:fs"; import path from "node:path"; // Monorepo: a single `.env` lives at the repository root; Next only reads the app directory. for (const candidate of [path.resolve(process.cwd(), "../../.env"), path.resolve(process.cwd(), ".env")]) { if (existsSync(candidate)) { try { process.loadEnvFile(candidate); } catch { /* ignore malformed env */ } } } // Dev: API on :8391 (repo .env). Production: the API process is the public edge (:8380) and proxies non-/v1 paths here (:8382). const API_URL = (process.env.API_URL ?? "http://127.0.0.1:8391").replace(/\/$/, ""); const isDevApi = /:8391$/.test(API_URL) || /localhost|127\.0\.0\.1/.test(API_URL) && process.env.NODE_ENV !== "production"; const nextConfig: NextConfig = { distDir: process.env.NEXT_DIST_DIR || ".next", reactStrictMode: true, poweredByHeader: false, allowedDevOrigins: ["127.0.0.1", "localhost"], outputFileTracingRoot: path.resolve(__dirname, "../.."), experimental: { optimizePackageImports: ["lucide-react"] }, env: { // In development the browser talks to the API directly for WebSocket (rewrites do not proxy upgrades). NEXT_PUBLIC_WS_URL: process.env.NEXT_PUBLIC_WS_URL ?? (isDevApi ? API_URL.replace(/^http/, "ws") + "/v1/stream" : ""), NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL ?? process.env.MA_SITE_URL ?? "https://www.market-atlas.co", }, async rewrites() { return [{ source: "/v1/:path*", destination: `${API_URL}/v1/:path*` }]; }, async headers() { const PUBLIC_CACHE = { key: "Cache-Control", value: "public, s-maxage=60, stale-while-revalidate=600" }; const NO_STORE = { key: "Cache-Control", value: "private, no-store" }; return [ { source: "/(.*)", headers: [ { key: "X-Content-Type-Options", value: "nosniff" }, { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, { key: "X-Frame-Options", value: "SAMEORIGIN" }, { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" }, ], }, { source: "/methodology", headers: [PUBLIC_CACHE] }, { source: "/developers", headers: [PUBLIC_CACHE] }, { source: "/licensing", headers: [PUBLIC_CACHE] }, { source: "/admin/:path*", headers: [NO_STORE] }, ]; }, }; export default nextConfig;