/** @type {import('next').NextConfig} */ // Backend origin for API/upload proxying. Configurable per environment instead of // being hardcoded to localhost. const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:3001'; // Extra image hosts can be allowed via a comma-separated env var (e.g. a CDN). const extraImageHosts = (process.env.NEXT_PUBLIC_IMAGE_HOSTS || '') .split(',') .map((h) => h.trim()) .filter(Boolean) .map((hostname) => ({ protocol: 'https', hostname })); const securityHeaders = [ { key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'X-Frame-Options', value: 'SAMEORIGIN' }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, { key: 'X-XSS-Protection', value: '0' }, { key: 'Permissions-Policy', value: 'camera=(self), microphone=(), geolocation=()' }, ]; const nextConfig = { images: { // Restrict remote image sources to a known allowlist instead of allowing any // https host (which let the Next image optimizer be used as an open proxy). remotePatterns: [ { protocol: 'https', hostname: 'images.unsplash.com' }, { protocol: 'http', hostname: 'localhost', port: '3001' }, ...extraImageHosts, ], }, async headers() { return [ { source: '/:path*', headers: securityHeaders, }, ]; }, async rewrites() { return [ { source: '/api/:path*', destination: `${BACKEND_URL}/api/:path*`, }, { source: '/uploads/:path*', destination: `${BACKEND_URL}/uploads/:path*`, }, ]; }, }; module.exports = nextConfig;