📄 production optimizations
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
// ============================================
|
||||
// Next.js 16 Configuration
|
||||
// ============================================
|
||||
// This configuration is optimized for Next.js 16
|
||||
// Deprecated options have been removed (swcMinify, reactStrictMode)
|
||||
// SWC minification is now default in Next.js 16
|
||||
|
||||
|
||||
// Production-ready Next.js configuration with standalone output
|
||||
// This configuration is optimized for Docker deployment with minimal image size
|
||||
@@ -37,6 +44,14 @@ const nextConfig = {
|
||||
// Image sizes for <Image> component size prop
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
|
||||
// Cache optimized images for 30 days
|
||||
minimumCacheTTL: 60 * 60 * 24 * 30,
|
||||
|
||||
// Allow SVG rendering (with security measures)
|
||||
dangerouslyAllowSVG: true,
|
||||
contentDispositionType: 'attachment',
|
||||
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
|
||||
|
||||
// Disable image optimization during build (optional)
|
||||
// Uncomment if build times are too long
|
||||
// unoptimized: false,
|
||||
@@ -55,8 +70,6 @@ const nextConfig = {
|
||||
// Performance Optimization
|
||||
// ============================================
|
||||
|
||||
// Enable SWC minification (faster than Terser)
|
||||
swcMinify: true,
|
||||
|
||||
// Compress static pages (reduces bandwidth)
|
||||
compress: true,
|
||||
@@ -95,9 +108,6 @@ const nextConfig = {
|
||||
|
||||
// ESLint during build
|
||||
// Set to false to skip linting (not recommended)
|
||||
eslint: {
|
||||
// ignoreDuringBuilds: false,
|
||||
},
|
||||
|
||||
// ============================================
|
||||
// Experimental Features (Next.js 16)
|
||||
@@ -111,35 +121,94 @@ const nextConfig = {
|
||||
static: 180,
|
||||
},
|
||||
|
||||
// Optimize package imports for smaller bundles
|
||||
optimizePackageImports: [
|
||||
'react-markdown',
|
||||
'rehype-raw',
|
||||
'rehype-sanitize',
|
||||
'remark-gfm',
|
||||
],
|
||||
|
||||
// Enable PPR (Partial Prerendering) - Next.js 16 feature
|
||||
// Uncomment to enable (currently in beta)
|
||||
// ppr: false,
|
||||
},
|
||||
|
||||
// ============================================
|
||||
// Headers (Optional)
|
||||
// Security Headers (PRODUCTION READY)
|
||||
// ============================================
|
||||
// Custom headers for all routes
|
||||
// Note: Caddy/Nginx reverse proxy can also set these headers
|
||||
// Uncomment if you want Next.js to handle headers instead
|
||||
//
|
||||
// Comprehensive security headers for public deployment
|
||||
// Note: Caddy reverse proxy may also set these as backup
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
source: '/:path*',
|
||||
headers: [
|
||||
// Prevent MIME type sniffing
|
||||
{
|
||||
key: 'X-Content-Type-Options',
|
||||
value: 'nosniff',
|
||||
},
|
||||
// Prevent clickjacking
|
||||
{
|
||||
key: 'X-Frame-Options',
|
||||
value: 'DENY',
|
||||
},
|
||||
// XSS Protection (legacy browsers)
|
||||
{
|
||||
key: 'X-XSS-Protection',
|
||||
value: '1; mode=block',
|
||||
},
|
||||
// HSTS - Force HTTPS for 1 year
|
||||
{
|
||||
key: 'Strict-Transport-Security',
|
||||
value: 'max-age=31536000; includeSubDomains; preload',
|
||||
},
|
||||
// Referrer Policy - Protect user privacy
|
||||
{
|
||||
key: 'Referrer-Policy',
|
||||
value: 'strict-origin-when-cross-origin',
|
||||
},
|
||||
// Permissions Policy - Disable unnecessary browser features
|
||||
{
|
||||
key: 'Permissions-Policy',
|
||||
value: 'camera=(), microphone=(), geolocation=(), interest-cohort=()',
|
||||
},
|
||||
// Content Security Policy - Restrict resource loading
|
||||
// Note: Next.js requires 'unsafe-inline' for styled-jsx
|
||||
{
|
||||
key: 'Content-Security-Policy',
|
||||
value: [
|
||||
"default-src 'self'",
|
||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval'",
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data: https:",
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self'",
|
||||
"frame-ancestors 'none'",
|
||||
"base-uri 'self'",
|
||||
"form-action 'self'",
|
||||
].join('; '),
|
||||
},
|
||||
],
|
||||
},
|
||||
// Aggressive caching for static assets
|
||||
{
|
||||
source: '/_next/static/:path*',
|
||||
headers: [
|
||||
{
|
||||
key: 'Cache-Control',
|
||||
value: 'public, max-age=31536000, immutable',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
source: '/images/:path*',
|
||||
headers: [
|
||||
{
|
||||
key: 'Cache-Control',
|
||||
value: 'public, max-age=31536000, immutable',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user