BankBot-AI / frontend /next.config.mjs
mohsin-devs's picture
Deploy to HF
a282d4b
/** @type {import('next').NextConfig} */
const nextConfig = {
// Standalone output for optimized Docker/HF production builds
output: "standalone",
// Compress responses
compress: true,
// Image optimization
images: {
domains: ["github.com"],
formats: ["image/avif", "image/webp"],
},
// Security headers
async headers() {
const apiUrl = process.env.NEXT_PUBLIC_API_URL || "";
const wsUrl = apiUrl
? apiUrl.replace(/^https/, "wss").replace(/^http/, "ws")
: "";
// CSP connect-src: allow same-origin + explicit API URL if set
const connectSrc = ["'self'", apiUrl, wsUrl]
.filter(Boolean)
.join(" ");
return [
{
source: "/(.*)",
headers: [
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "X-Frame-Options", value: "SAMEORIGIN" }, // HF embeds in iframe
{ 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-eval' 'unsafe-inline'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https: blob:",
"font-src 'self' data:",
`connect-src ${connectSrc} ws: wss:`,
"worker-src 'self' blob:",
].join("; "),
},
],
},
];
},
// API proxy rewrites
// When NEXT_PUBLIC_API_URL is set: proxy to external backend
// When empty (HF mode): Nginx handles /api/* routing internally
async rewrites() {
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
if (!apiUrl) {
// HF mode: no rewrites needed — Nginx routes /api/* to FastAPI
return [];
}
return [
{
source: "/api/:path*",
destination: `${apiUrl}/api/:path*`,
},
];
},
// Webpack optimizations
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
net: false,
tls: false,
};
}
return config;
},
};
export default nextConfig;