| import type { NextConfig } from "next"; |
| import withBundleAnalyzer from "@next/bundle-analyzer"; |
|
|
| const nextConfig: NextConfig = { |
| images: { |
| remotePatterns: [ |
| { |
| protocol: "https", |
| hostname: "lh3.googleusercontent.com", |
| }, |
| ], |
| }, |
| experimental: { |
| serverActions: { |
| allowedOrigins: ["shubhjn-autoloop.hf.space", "localhost:3000"], |
| }, |
| optimizePackageImports: [ |
| "lodash-es", |
| "date-fns", |
| "@radix-ui/react-icons", |
| "recharts", |
| ], |
| }, |
| |
| turbopack: { |
| resolveAlias: { |
| "@": "./", |
| }, |
| }, |
| webpack: (config, { isServer }) => { |
| |
| if (!isServer) { |
| config.optimization = { |
| ...config.optimization, |
| splitChunks: { |
| chunks: "all", |
| cacheGroups: { |
| |
| vendor: { |
| test: /[\\/]node_modules[\\/]/, |
| name: "vendors", |
| priority: 10, |
| reuseExistingChunk: true, |
| }, |
| |
| nextInternal: { |
| test: /[\\/]node_modules[\\/](react|next)[\\/]/, |
| name: "next-internals", |
| priority: 20, |
| reuseExistingChunk: true, |
| }, |
| |
| ui: { |
| test: /[\\/](components|ui)[\\/]/, |
| name: "ui", |
| priority: 5, |
| minSize: 20000, |
| reuseExistingChunk: true, |
| }, |
| }, |
| }, |
| }; |
| } |
| return config; |
| }, |
| headers: async () => { |
| return [ |
| { |
| source: "/(.*)", |
| 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" }, |
| { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" }, |
|
|
| |
| { |
| key: "Content-Security-Policy", |
| value: [ |
| "default-src 'self'", |
| "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://cdn.statically.io", |
| "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", |
| "img-src 'self' data: https: blob:", |
| "font-src 'self' https://fonts.gstatic.com", |
| "connect-src 'self' https: wss:", |
| "frame-src 'self' https:", |
| "object-src 'none'", |
| "media-src 'self'", |
| "form-action 'self'", |
| "frame-ancestors 'none'", |
| "base-uri 'self'", |
| "upgrade-insecure-requests", |
| ].join("; "), |
| }, |
|
|
| |
| { |
| key: "Strict-Transport-Security", |
| value: "max-age=31536000; includeSubDomains; preload", |
| }, |
|
|
| |
| { key: "X-Frame-Options", value: "SAMEORIGIN" }, |
|
|
| |
| { key: "X-XSS-Protection", value: "1; mode=block" }, |
|
|
| |
| { key: "X-Content-Type-Options", value: "nosniff" }, |
|
|
| |
| { |
| key: "Permissions-Policy", |
| value: "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()", |
| }, |
| ], |
| }, |
| |
| { |
| source: "/api/(.*)", |
| headers: [ |
| { key: "X-Content-Type-Options", value: "nosniff" }, |
| { key: "X-Frame-Options", value: "DENY" }, |
| { key: "Content-Type", value: "application/json; charset=utf-8" }, |
| ], |
| }, |
| ]; |
| }, |
| }; |
|
|
| export default withBundleAnalyzer({ |
| enabled: process.env.ANALYZE === "true", |
| })(nextConfig); |
|
|