/** @type {import('next').NextConfig} */ import bundleAnalyzer from "@next/bundle-analyzer"; const withBundleAnalyzer = bundleAnalyzer({ enabled: process.env.ANALYZE === "true", }); const nextConfig = { images: { remotePatterns: [ { protocol: "https", hostname: "**", }, ], minimumCacheTTL: 3600, formats: ["image/avif", "image/webp"], // 预设头像库使用本地 SVG(/avatars/*.svg),需放行 SVG 走优化器,否则 next/image 返回 400 dangerouslyAllowSVG: true, // SVG 以 sandbox 方式渲染,禁用脚本,防止恶意 SVG 执行 contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;", }, compress: true, poweredByHeader: false, reactStrictMode: true, webpack: (config, { isServer }) => { config.watchOptions = { ...config.watchOptions, ignored: [ "**/node_modules/**", "**/.git/**", "**/System Volume Information/**", "**/DumpStack.log.tmp", "**/pagefile.sys", ], poll: false, }; return config; }, onDemandEntries: { maxInactiveAge: 60 * 1000, pagesBufferLength: 5, }, experimental: { optimizeCss: false, }, headers: async () => { const isDev = process.env.NODE_ENV === "development"; const headers = [ { source: "/api/:path*", headers: [ { key: "X-Content-Type-Options", value: "nosniff" }, { key: "X-Frame-Options", value: "DENY" }, { key: "X-XSS-Protection", value: "1; mode=block" }, { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, ], }, { source: "/:path*", headers: [ { key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains; preload" }, { key: "Content-Security-Policy", value: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data: blob:; font-src 'self' data:; connect-src 'self' https: wss:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" }, { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=(), payment=()" }, { key: "X-Content-Type-Options", value: "nosniff" }, { key: "X-Frame-Options", value: "DENY" }, { key: "X-XSS-Protection", value: "1; mode=block" }, { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, ], }, { source: "/logos/:path*", headers: [ { key: "Cache-Control", value: isDev ? "no-cache" : "public, max-age=86400, immutable" }, ], }, ]; if (isDev) { headers.push({ source: "/(.*)", headers: [ { key: "Cache-Control", value: "no-store, no-cache, must-revalidate, proxy-revalidate" }, ], }); } else { headers.push({ source: "/_next/static/:path*", headers: [ { key: "Cache-Control", value: "public, max-age=31536000, immutable" }, ], }); } return headers; }, }; export default withBundleAnalyzer(nextConfig);