Spaces:
Build error
Build error
| /** @type {import('next').NextConfig} */ | |
| const nextConfig = { | |
| // Standalone output for optimized Docker/HF production builds | |
| output: "standalone", | |
| // Compress responses | |
| compress: true, | |
| // Image optimization | |
| images: { | |
| domains: ["github.com"], | |
| formats: ["image/avif", "image/webp"], | |
| }, | |
| // Security headers | |
| async headers() { | |
| const apiUrl = process.env.NEXT_PUBLIC_API_URL || ""; | |
| const wsUrl = apiUrl | |
| ? apiUrl.replace(/^https/, "wss").replace(/^http/, "ws") | |
| : ""; | |
| // CSP connect-src: allow same-origin + explicit API URL if set | |
| const connectSrc = ["'self'", apiUrl, wsUrl] | |
| .filter(Boolean) | |
| .join(" "); | |
| return [ | |
| { | |
| source: "/(.*)", | |
| headers: [ | |
| { key: "X-Content-Type-Options", value: "nosniff" }, | |
| { key: "X-Frame-Options", value: "SAMEORIGIN" }, // HF embeds in iframe | |
| { key: "X-XSS-Protection", value: "1; mode=block" }, | |
| { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, | |
| { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" }, | |
| { | |
| key: "Content-Security-Policy", | |
| value: [ | |
| "default-src 'self'", | |
| "script-src 'self' 'unsafe-eval' 'unsafe-inline'", | |
| "style-src 'self' 'unsafe-inline'", | |
| "img-src 'self' data: https: blob:", | |
| "font-src 'self' data:", | |
| `connect-src ${connectSrc} ws: wss:`, | |
| "worker-src 'self' blob:", | |
| ].join("; "), | |
| }, | |
| ], | |
| }, | |
| ]; | |
| }, | |
| // API proxy rewrites | |
| // When NEXT_PUBLIC_API_URL is set: proxy to external backend | |
| // When empty (HF mode): Nginx handles /api/* routing internally | |
| async rewrites() { | |
| const apiUrl = process.env.NEXT_PUBLIC_API_URL; | |
| if (!apiUrl) { | |
| // HF mode: no rewrites needed — Nginx routes /api/* to FastAPI | |
| return []; | |
| } | |
| return [ | |
| { | |
| source: "/api/:path*", | |
| destination: `${apiUrl}/api/:path*`, | |
| }, | |
| ]; | |
| }, | |
| // Webpack optimizations | |
| webpack: (config, { isServer }) => { | |
| if (!isServer) { | |
| config.resolve.fallback = { | |
| ...config.resolve.fallback, | |
| fs: false, | |
| net: false, | |
| tls: false, | |
| }; | |
| } | |
| return config; | |
| }, | |
| }; | |
| export default nextConfig; | |