next.config.js 中有哪些常见配置?如何配置重定向(redirects)、重写(rewrites)、自定义头部(headers)和环境变量?
基础配置结构
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// 基础配置
reactStrictMode: true,
swcMinify: true,
// 实验性功能
experimental: {
appDir: true,
serverComponentsExternalPackages: ['mongoose'],
},
// 环境变量
env: {
CUSTOM_KEY: process.env.CUSTOM_KEY,
},
// 公共运行时配置
publicRuntimeConfig: {
apiUrl: process.env.API_URL,
},
// 服务器运行时配置
serverRuntimeConfig: {
secret: process.env.SECRET,
},
}
module.exports = nextConfig
重定向配置
1. 基础重定向
// next.config.js
const nextConfig = {
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true, // 301 重定向
},
{
source: '/temporary-redirect',
destination: '/new-location',
permanent: false, // 302 重定向
},
]
},
}
2. 动态重定向
// next.config.js
const nextConfig = {
async redirects() {
return [
{
source: '/blog/:slug',
destination: '/posts/:slug',
permanent: true,
},
{
source: '/user/:id',
destination: '/profile/:id',
permanent: true,
},
{
source: '/category/:category',
destination: '/categories/:category',
permanent: true,
},
]
},
}
3. 条件重定向
// next.config.js
const nextConfig = {
async redirects() {
return [
{
source: '/admin',
destination: '/admin/dashboard',
permanent: false,
has: [
{
type: 'cookie',
key: 'user-role',
value: 'admin',
},
],
},
{
source: '/login',
destination: '/dashboard',
permanent: false,
has: [
{
type: 'cookie',
key: 'auth-token',
},
],
},
]
},
}
4. 外部重定向
// next.config.js
const nextConfig = {
async redirects() {
return [
{
source: '/external-link',
destination: 'https://example.com',
permanent: true,
},
{
source: '/docs',
destination: 'https://docs.example.com',
permanent: false,
},
]
},
}
重写配置
1. 基础重写
// next.config.js
const nextConfig = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'https://api.example.com/:path*',
},
{
source: '/proxy/:path*',
destination: 'https://backend.example.com/:path*',
},
]
},
}
2. 内部重写
// next.config.js
const nextConfig = {
async rewrites() {
return [
{
source: '/dashboard',
destination: '/app/dashboard',
},
{
source: '/profile',
destination: '/app/profile',
},
]
},
}
3. 条件重写
// next.config.js
const nextConfig = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'https://api.example.com/:path*',
has: [
{
type: 'header',
key: 'x-api-key',
},
],
},
{
source: '/api/:path*',
destination: 'https://staging-api.example.com/:path*',
has: [
{
type: 'header',
key: 'x-environment',
value: 'staging',
},
],
},
]
},
}
自定义头部配置
1. 安全头部
// next.config.js
const nextConfig = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-XSS-Protection',
value: '1; mode=block',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
],
},
]
},
}
2. API 头部
// next.config.js
const nextConfig = {
async headers() {
return [
{
source: '/api/(.*)',
headers: [
{
key: 'Access-Control-Allow-Origin',
value: 'https://example.com',
},
{
key: 'Access-Control-Allow-Methods',
value: 'GET, POST, PUT, DELETE, OPTIONS',
},
{
key: 'Access-Control-Allow-Headers',
value: 'Content-Type, Authorization',
},
{
key: 'Access-Control-Max-Age',
value: '86400',
},
],
},
]
},
}
3. 缓存头部
// next.config.js
const nextConfig = {
async headers() {
return [
{
source: '/static/(.*)',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
{
source: '/api/(.*)',
headers: [
{
key: 'Cache-Control',
value: 'no-cache, no-store, must-revalidate',
},
],
},
]
},
}
环境变量配置
1. 基础环境变量
// next.config.js
const nextConfig = {
env: {
CUSTOM_KEY: process.env.CUSTOM_KEY,
API_URL: process.env.API_URL,
DATABASE_URL: process.env.DATABASE_URL,
},
}
2. 公共运行时配置
// next.config.js
const nextConfig = {
publicRuntimeConfig: {
apiUrl: process.env.API_URL,
appName: process.env.APP_NAME,
version: process.env.APP_VERSION,
},
}
3. 服务器运行时配置
// next.config.js
const nextConfig = {
serverRuntimeConfig: {
secret: process.env.SECRET,
databaseUrl: process.env.DATABASE_URL,
jwtSecret: process.env.JWT_SECRET,
},
}
4. 条件环境变量
// next.config.js
const nextConfig = {
env: {
API_URL:
process.env.NODE_ENV === 'production'
? 'https://api.example.com'
: 'http://localhost:3001',
DEBUG: process.env.NODE_ENV === 'development',
},
}
高级配置
1. 图片优化配置
// next.config.js
const nextConfig = {
images: {
domains: ['example.com', 'cdn.example.com'],
formats: ['image/webp', 'image/avif'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
minimumCacheTTL: 60,
dangerouslyAllowSVG: true,
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
}
2. Webpack 配置
// next.config.js
const nextConfig = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// 自定义 webpack 配置
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components'),
'@utils': path.resolve(__dirname, 'src/utils'),
}
// 添加自定义插件
config.plugins.push(
new webpack.DefinePlugin({
'process.env.CUSTOM_VAR': JSON.stringify(process.env.CUSTOM_VAR),
})
)
return config
},
}
3. 实验性功能
// next.config.js
const nextConfig = {
experimental: {
appDir: true,
serverComponentsExternalPackages: ['mongoose', 'prisma'],
serverActions: true,
mdxRs: true,
turbo: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
},
}
实际应用示例
1. 多环境配置
// next.config.js
const isProduction = process.env.NODE_ENV === 'production'
const isDevelopment = process.env.NODE_ENV === 'development'
const nextConfig = {
// 基础配置
reactStrictMode: true,
swcMinify: isProduction,
// 环境变量
env: {
API_URL: process.env.API_URL,
APP_NAME: process.env.APP_NAME,
},
// 重定向
async redirects() {
return [
{
source: '/old-dashboard',
destination: '/dashboard',
permanent: true,
},
]
},
// 重写
async rewrites() {
return [
{
source: '/api/:path*',
destination: `${process.env.API_URL}/:path*`,
},
]
},
// 头部
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
],
},
]
},
// 图片优化
images: {
domains: ['example.com'],
formats: ['image/webp', 'image/avif'],
},
}
module.exports = nextConfig
2. 国际化配置
// next.config.js
const nextConfig = {
i18n: {
locales: ['en', 'zh', 'ja'],
defaultLocale: 'en',
localeDetection: false,
},
async redirects() {
return [
{
source: '/zh/:path*',
destination: '/:path*?locale=zh',
permanent: false,
},
]
},
}
3. PWA 配置
// next.config.js
const withPWA = require('next-pwa')({
dest: 'public',
register: true,
skipWaiting: true,
})
const nextConfig = {
async headers() {
return [
{
source: '/manifest.json',
headers: [
{
key: 'Content-Type',
value: 'application/manifest+json',
},
],
},
]
},
}
module.exports = withPWA(nextConfig)
最佳实践
1. 配置分离
// config/next.config.base.js
const baseConfig = {
reactStrictMode: true,
swcMinify: true,
}
// config/next.config.dev.js
const devConfig = {
...baseConfig,
env: {
API_URL: 'http://localhost:3001',
},
}
// config/next.config.prod.js
const prodConfig = {
...baseConfig,
env: {
API_URL: 'https://api.example.com',
},
}
// next.config.js
const config = process.env.NODE_ENV === 'production' ? prodConfig : devConfig
module.exports = config
2. 环境变量验证
// lib/env.js
const requiredEnvVars = ['API_URL', 'DATABASE_URL', 'JWT_SECRET']
for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
throw new Error(`Missing required environment variable: ${envVar}`)
}
}
export const env = {
API_URL: process.env.API_URL,
DATABASE_URL: process.env.DATABASE_URL,
JWT_SECRET: process.env.JWT_SECRET,
}
总结
Next.js 配置的主要方面:
重定向:
- 基础重定向和动态重定向
- 条件重定向
- 外部重定向
重写:
- API 代理
- 内部路由重写
- 条件重写
头部配置:
- 安全头部
- CORS 头部
- 缓存头部
环境变量:
- 基础环境变量
- 公共和服务器运行时配置
- 条件环境变量
最佳实践:
- 配置分离
- 环境变量验证
- 安全配置
- 性能优化