Spaces:
Configuration error
Configuration error
| import type { NextConfig } from "next"; | |
| const nextConfig: NextConfig = { | |
| // Image optimization – whitelist only known-safe domains (no wildcard **) | |
| images: { | |
| remotePatterns: [ | |
| // GitHub avatars (OAuth) | |
| { protocol: "https", hostname: "avatars.githubusercontent.com" }, | |
| // Google avatars (OAuth) | |
| { protocol: "https", hostname: "lh3.googleusercontent.com" }, | |
| { protocol: "https", hostname: "lh4.googleusercontent.com" }, | |
| { protocol: "https", hostname: "lh5.googleusercontent.com" }, | |
| // Stack Auth CDN | |
| { protocol: "https", hostname: "*.stackauth.com" }, | |
| // Prompt preview / gallery images (Cloudflare R2 / storage) | |
| { protocol: "https", hostname: "imagedelivery.net" }, | |
| { protocol: "https", hostname: "images.unsplash.com" }, | |
| // AI image CDNs | |
| { protocol: "https", hostname: "oaidalleapiprodscus.blob.core.windows.net" }, | |
| { protocol: "https", hostname: "cdn.midjourney.com" }, | |
| { protocol: "https", hostname: "image.civitai.com" }, | |
| ], | |
| formats: ["image/avif", "image/webp"], | |
| }, | |
| // Security headers | |
| async headers() { | |
| return [ | |
| { | |
| source: "/(.*)", | |
| headers: [ | |
| { key: "X-Frame-Options", value: "SAMEORIGIN" }, | |
| { key: "X-Content-Type-Options", value: "nosniff" }, | |
| { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, | |
| { key: "X-DNS-Prefetch-Control", value: "on" }, | |
| { key: "X-Permitted-Cross-Domain-Policies", value: "none" }, | |
| { key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains; preload" }, | |
| { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" }, | |
| { | |
| key: "Content-Security-Policy", | |
| value: [ | |
| "default-src 'self'", | |
| "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://challenges.cloudflare.com https://www.googletagmanager.com", | |
| "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", | |
| "font-src 'self' https://fonts.gstatic.com", | |
| "img-src 'self' data: blob: https:", | |
| "frame-src 'self' https://challenges.cloudflare.com", | |
| "connect-src 'self' https://api.openai.com https://api.anthropic.com https://generativelanguage.googleapis.com https://challenges.cloudflare.com wss: ws:", | |
| "media-src 'self' blob:", | |
| "worker-src 'self' blob:", | |
| ].join("; "), | |
| }, | |
| ], | |
| }, | |
| { | |
| source: "/logos/(.*)", | |
| headers: [ | |
| { key: "Cache-Control", value: "public, max-age=31536000, immutable" }, | |
| ], | |
| }, | |
| { | |
| source: "/(.*\\.(?:svg|png|jpg|jpeg|gif|ico|woff2|woff|ttf))", | |
| headers: [ | |
| { key: "Cache-Control", value: "public, max-age=86400, stale-while-revalidate=3600" }, | |
| ], | |
| }, | |
| ]; | |
| }, | |
| // Performance optimizations – tree-shake large packages | |
| experimental: { | |
| optimizePackageImports: [ | |
| "lucide-react", | |
| "react-icons", | |
| "framer-motion", | |
| "recharts", | |
| "three", | |
| "@react-three/fiber", | |
| "@react-three/drei", | |
| "@radix-ui/react-dropdown-menu", | |
| "@radix-ui/react-select", | |
| "@radix-ui/react-tabs", | |
| "@radix-ui/react-tooltip", | |
| "@radix-ui/react-checkbox", | |
| "react-markdown", | |
| "zustand", | |
| ], | |
| }, | |
| }; | |
| export default nextConfig; | |