/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
compress: true,
// Edge runtime for global deployment
experimental: {
runtime: 'edge',
serverActions: true,
optimizePackageImports: [
'lucide-react',
'framer-motion',
'@radix-ui/react-*',
],
},
// Image optimization
images: {
domains: ['raw.githubusercontent.com'],
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
minimumCacheTTL: 31536000, // 1 year
},
// Headers for security and performance
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
},
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
},
{
key: 'X-Content-Type-Options',
value: 'nosniff'
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
},
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()'
}
]
},
{
source: '/api/:path*',
headers: [
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'GET,POST,OPTIONS' },
{ key: 'Access-Control-Allow-Headers', value: 'Content-Type, Authorization' }
]
}
]
},
// Redirects for legacy URLs
async redirects() {
return [
{
source: '/campaign/:path*',
destination: '/x402-protocol',
permanent: true
},
{
source: '/docs/old/:path*',
destination: '/docs/:path*',
permanent: true
}
]
},
// Webpack optimizations
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
net: false,
tls: false,
}
// Split vendor chunks for optimal caching
config.optimization = {
...config.optimization,
splitChunks: {
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
framework: {
name: 'framework',
chunks: 'all',
test: /(?<!node_modules.*)[\\/]node_modules[\\/](react|react-dom|scheduler|prop-types|use-subscription)[\\/]/,
priority: 40,
enforce: true,
},
lib: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const match = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)
const packageName = match ? match[1] : 'vendor'
return `npm.${packageName.replace('@', '')}`
},
priority: 30,
minChunks: 1,
reuseExistingChunk: true,
},
commons: {
name: 'commons',
minChunks: 2,
priority: 20,
},
},
},
}
}
// Bundle analyzer in development
if (process.env.ANALYZE === 'true') {
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
})
)
}
return config
}
}
module.exports = nextConfig