| |
| const nextConfig = { |
| output: 'standalone', |
| reactStrictMode: true, |
| swcMinify: true, |
|
|
| |
| experimental: { |
| serverComponentsExternalPackages: ['better-sqlite3'], |
| }, |
|
|
| |
| async headers() { |
| |
| const allowedOrigins = (process.env.ALLOWED_ORIGINS || '') |
| .split(',') |
| .map((o) => o.trim()) |
| .filter(Boolean); |
|
|
| const corsHeaders = [ |
| { |
| key: 'Access-Control-Allow-Methods', |
| value: 'GET, POST, PUT, DELETE, OPTIONS', |
| }, |
| { |
| key: 'Access-Control-Allow-Headers', |
| value: 'Content-Type, Authorization', |
| }, |
| { |
| key: 'Access-Control-Allow-Credentials', |
| value: 'true', |
| }, |
| |
| { |
| key: 'Access-Control-Allow-Origin', |
| value: allowedOrigins[0] || '*', |
| }, |
| ]; |
|
|
| return [ |
| |
| { |
| source: '/api/:path*', |
| headers: corsHeaders, |
| }, |
| { |
| source: '/(.*)', |
| headers: [ |
| { key: 'X-Content-Type-Options', value: 'nosniff' }, |
| |
| |
| |
| { key: 'X-XSS-Protection', value: '1; mode=block' }, |
| { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, |
| |
| |
| |
| |
| ...(process.env.NODE_ENV === 'production' |
| ? [ |
| { |
| key: 'Strict-Transport-Security', |
| value: 'max-age=63072000; includeSubDomains', |
| }, |
| ] |
| : []), |
| { |
| key: 'Content-Security-Policy', |
| value: [ |
| "default-src 'self'", |
| "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdnjs.cloudflare.com", |
| "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", |
| "font-src 'self' https://fonts.gstatic.com data:", |
| "img-src 'self' https: data: blob:", |
| "connect-src 'self' https://router.huggingface.co https://api-inference.huggingface.co https://overpass-api.de https://nominatim.openstreetmap.org https://*.hf.space wss:", |
| "frame-src 'self' https://www.openstreetmap.org", |
| "frame-ancestors 'self' https://huggingface.co https://*.hf.space", |
| "media-src 'self' blob:", |
| "worker-src 'self' blob:", |
| ].join('; '), |
| }, |
| { |
| key: 'Permissions-Policy', |
| value: 'microphone=(self), camera=(self), geolocation=*', |
| }, |
| ], |
| }, |
| { |
| source: '/sw.js', |
| headers: [ |
| { key: 'Cache-Control', value: 'no-cache, no-store, must-revalidate' }, |
| { key: 'Service-Worker-Allowed', value: '/' }, |
| ], |
| }, |
| { |
| source: '/manifest.json', |
| headers: [ |
| { key: 'Content-Type', value: 'application/manifest+json' }, |
| ], |
| }, |
| ]; |
| }, |
|
|
| |
| images: { |
| formats: ['image/avif', 'image/webp'], |
| remotePatterns: [ |
| { protocol: 'https', hostname: '*.huggingface.co' }, |
| ], |
| }, |
|
|
| |
| poweredByHeader: false, |
|
|
| |
| compress: true, |
| }; |
|
|
| module.exports = nextConfig; |
|
|