next.config.js Configuration Mistakes That Break Your Build
How to identify and fix common next.config.js configuration errors that cause build failures in Next.js projects
next.config.js Configuration Mistakes That Break Your Build
Introduction
The next.config.js file is deceptively simple. It looks like a plain JavaScript object, but a single wrong property can cause your entire build to fail with cryptic error messages. After helping several developers in the Lisbon meetups debug their Next.js builds, I noticed that the same configuration mistakes kept appearing over and over again.
This post catalogs the most common next.config.js errors I have encountered, explains why they cause failures, and provides working configurations for each scenario.
Environment
- OS: Windows 11
- Node.js: v20.10.0
- Next.js: 14.0.4
- Package Manager: npm 10.2.3
Problem
Running next build produces errors that do not clearly indicate the root cause:
Error occurred prerendering page "/"
Error: Export encountered an error reading `/`, exiting the build process.
Build error occurred
Error: Build failed with 1 errorOr worse, the build completes but the deployed application behaves incorrectly:
warn - Invalid next.config.js option: `imageDomains`
warn - Valid options: images, experimental, i18n, ...Analysis
The root cause is almost always a typo, incorrect nesting, or using a deprecated option. Here are the five most common mistakes I have seen:
Mistake 1: Incorrect images configuration path
// WRONG
module.exports = {
images: {
domains: ['example.com'], // This works but is deprecated
},
}Mistake 2: Using CommonJS and ESM syntax together
// WRONG - mixing require and export
const { createRequire } = require('module')
export default {
// config
}Mistake 3: Returning async operations in a synchronous config
// WRONG
module.exports = {
webpack: async (config) => {
const module = await import('some-module')
config.resolve.alias['@'] = module.path
return config
},
}Mistake 4: Incorrect rewrites return format
// WRONG - returning an object instead of an array
module.exports = {
async rewrites() {
return {
beforeFiles: [{ source: '/api/:path*', destination: '/backend/:path*' }],
}
},
}Mistake 5: Missing reactStrictMode type safety
// WRONG - missing the wrapper
module.exports = {
reactStrictMode: 'true', // String instead of boolean
}Solution
Here are the corrected configurations for each mistake:
Fix 1: Use the new remotePatterns format
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
pathname: '/images/**',
},
{
protocol: 'https',
hostname: '*.cdn.example.com',
},
],
},
}
module.exports = nextConfigFix 2: Stick to one module system
// next.config.js (CommonJS - recommended for Next.js)
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
poweredByHeader: false,
}
module.exports = nextConfigFix 3: Handle async webpack configuration properly
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer }) => {
config.resolve.alias['@'] = path.join(__dirname, 'src')
return config
},
}
module.exports = nextConfigFix 4: Return arrays from rewrites
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'https://backend.example.com/:path*',
},
]
},
}
module.exports = nextConfigFix 5: Validate your configuration
// scripts/validate-config.js
const config = require('../next.config.js')
function validateConfig(config) {
const errors = []
if (typeof config.reactStrictMode !== 'boolean') {
errors.push('reactStrictMode must be a boolean')
}
if (config.images?.domains) {
errors.push('images.domains is deprecated, use remotePatterns')
}
if (errors.length > 0) {
console.error('Configuration errors:', errors)
process.exit(1)
}
console.log('Configuration is valid!')
}
validateConfig(config)You can add this to your package.json:
{
"scripts": {
"validate": "node scripts/validate-config.js",
"build": "npm run validate && next build"
}
}Lessons Learned
Use TypeScript for next.config.js. Next.js supports
next.config.tssince version 14. TypeScript catches configuration errors at edit time rather than build time.Always validate configuration in CI. Running a config validation step in your CI pipeline catches issues before they reach production.
Check the Next.js changelog when upgrading. Configuration options are frequently deprecated or renamed between major versions.
Keep a minimal configuration. Only add settings you actively need. The defaults are well-optimized for most use cases.
Use the
NEXT_DEBUG_BUILDenvironment variable when diagnosing build issues:
NEXT_DEBUG_BUILD=1 next buildThis logs additional information about what Next.js is doing during the build process.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.