import createNextIntlPlugin from "next-intl/plugin"; const withNextIntl = createNextIntlPlugin("./src/i18n/request.ts"); /** @type {import('next').NextConfig} */ const nextConfig = { output: "standalone", webpack: (config, { isServer, webpack }) => { if (!isServer) { config.output.globalObject = "self"; } // react-konva / konva must not load the Node `canvas` package in the browser bundle config.resolve.alias = { ...config.resolve.alias, canvas: false, }; config.plugins.push( new webpack.IgnorePlugin({ resourceRegExp: /^canvas$/, }) ); return config; }, images: { // Placeholder art is now a same-origin SVG from /api/placeholder (offline-safe). // dangerouslyAllowSVG only ever serves our own generated gradients — never user // uploads — and the CSP + attachment disposition neutralise any script content. dangerouslyAllowSVG: true, contentDispositionType: "attachment", contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;", }, // Required for ffmpeg.wasm (SharedArrayBuffer needs COOP + COEP headers) async headers() { return [ { source: "/(.*)", headers: [ { key: "Cross-Origin-Opener-Policy", value: "same-origin" }, { key: "Cross-Origin-Embedder-Policy", value: "require-corp" }, ], }, ]; }, }; export default withNextIntl(nextConfig);