/** @type {import('next').NextConfig} */ const nextConfig = { // Enable standalone output for optimized production deployment output: 'standalone', images: { // Enable image optimization in standalone mode unoptimized: false, remotePatterns: [ { protocol: 'http', hostname: 'localhost', port: '8000', pathname: '/media/**', }, { protocol: 'https', hostname: 'localhost', port: '8000', pathname: '/media/**', }, { protocol: 'http', hostname: 'localhost', port: '8080', pathname: '/images/**', }, { protocol: 'https', hostname: 'localhost', port: '8080', pathname: '/images/**', }, { protocol: 'https', hostname: 'images.unsplash.com', pathname: '/**', }, // Production domain configuration { protocol: 'https', hostname: 'gnxsoft.com', pathname: '/media/**', }, { protocol: 'https', hostname: 'gnxsoft.com', pathname: '/images/**', }, { protocol: 'https', hostname: 'gnxsoft.com', pathname: '/_next/static/**', }, { protocol: 'http', hostname: 'gnxsoft.com', pathname: '/media/**', }, { protocol: 'http', hostname: 'gnxsoft.com', pathname: '/images/**', }, { protocol: 'https', hostname: 'www.gnxsoft.com', pathname: '/media/**', }, { protocol: 'https', hostname: 'www.gnxsoft.com', pathname: '/images/**', }, { protocol: 'https', hostname: 'www.gnxsoft.com', pathname: '/_next/static/**', }, { protocol: 'http', hostname: 'www.gnxsoft.com', pathname: '/media/**', }, { protocol: 'http', hostname: 'www.gnxsoft.com', pathname: '/images/**', }, ], // Legacy domains format for additional compatibility domains: ['images.unsplash.com', 'gnxsoft.com', 'www.gnxsoft.com'], formats: ['image/avif', 'image/webp'], deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840], imageSizes: [16, 32, 48, 64, 96, 128, 256, 384], minimumCacheTTL: 60, }, sassOptions: { includePaths: ['./public/styles', './node_modules'], quietDeps: true, // Suppress deprecation warnings from dependencies }, // Compiler optimizations compiler: { removeConsole: process.env.NODE_ENV === 'production' ? { exclude: ['error', 'warn'], } : false, }, // Compression compress: true, // Production optimizations productionBrowserSourceMaps: false, // Performance optimizations (swcMinify removed - default in Next.js 15) // Enterprise Security Headers async headers() { return [ { source: '/:path*', headers: [ // Security Headers { key: 'X-DNS-Prefetch-Control', value: 'on' }, { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' }, { key: 'X-Frame-Options', value: 'SAMEORIGIN' }, { key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'X-XSS-Protection', value: '1; mode=block' }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=(), interest-cohort=()' }, { key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https: http://localhost:8000 http://localhost:8080; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' http://localhost:8000 https://www.google-analytics.com; frame-src 'self' https://www.google.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" }, // Performance Headers { key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }, ], }, // Static assets caching { source: '/images/:path*', headers: [ { key: 'Cache-Control', value: 'public, max-age=31536000, immutable', }, ], }, { source: '/icons/:path*', headers: [ { key: 'Cache-Control', value: 'public, max-age=31536000, immutable', }, ], }, // API responses - no cache for dynamic content { source: '/api/:path*', headers: [ { key: 'Cache-Control', value: 'no-store, must-revalidate', }, ], }, ] }, // Redirects for SEO async redirects() { return [ // Temporarily disabled - causing API issues // { // source: '/((?!api/).*)+/', // destination: '/$1', // permanent: true, // }, ] }, // Rewrites for API proxy (Production: routes /api to backend through nginx) async rewrites() { // In development, proxy to Django backend if (process.env.NODE_ENV === 'development') { return [ { source: '/api/:path*', destination: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'}/api/:path*`, }, { source: '/media/:path*', destination: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'}/media/:path*`, }, ] } // In production, add rewrite for media files so Next.js image optimization can access them // This allows Next.js to fetch media images from the internal backend during optimization return [ { source: '/media/:path*', destination: `${process.env.INTERNAL_API_URL || 'http://127.0.0.1:1086'}/media/:path*`, }, ] }, } module.exports = nextConfig