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: FastAPI on :8331 (see repo .env). Production sets API_URL=http://127.0.0.1:8321 in the mld manifest. const API_URL = (process.env.API_URL ?? 'http://127.0.0.1:8331').replace(/\/$/, ''); const nextConfig: NextConfig = { // NEXT_DIST_DIR lets parallel dev servers / builds use separate output dirs (default .next) 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'], }, // Browser-side fetches go to the same origin; the FastAPI service is loopback-only. async rewrites() { return [ { source: '/api/v1/:path*', destination: `${API_URL}/api/v1/:path*` }, { source: '/health', destination: `${API_URL}/health` }, ]; }, async headers() { const PUBLIC_CACHE = { key: 'Cache-Control', value: 'public, s-maxage=300, stale-while-revalidate=3600' }; 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=()' }, { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' }, ], }, { source: '/models/:path*', headers: [PUBLIC_CACHE] }, { source: '/companies/:path*', headers: [PUBLIC_CACHE] }, { source: '/papers/:path*', headers: [PUBLIC_CACHE] }, { source: '/providers/:path*', headers: [PUBLIC_CACHE] }, { source: '/benchmarks/:path*', headers: [PUBLIC_CACHE] }, { source: '/hardware/:path*', headers: [PUBLIC_CACHE] }, { source: '/api/:path*', headers: [NO_STORE] }, { source: '/admin/:path*', headers: [NO_STORE] }, ]; }, }; export default nextConfig;