How to fix "Image Optimization is not possible with output: export" in Next.js
My Next.js build fails after adding output: 'export' to next.config.js:
Error: Image Optimization using the default loader is not compatible with
`{ output: 'export' }`.
Possible solutions:
- Remove `{ output: 'export' }` and run "next start" to run server mode including the Image Optimization API.
- Configure `{ images: { unoptimized: true } }` in `next.config.js` to disable the Image Optimization API.
How do I keep using next/image with a static export?
Solution
The built-in Next.js Image Optimization requires a running Node.js server to resize and compress images on demand. A static export (output: 'export') produces only HTML, CSS, and JS files, so there is no server to handle those requests.
The simplest fix is to add unoptimized: true to the images config. This tells Next.js to skip server-side optimization and serve the original images as-is:
// next.config.js
const nextConfig = {
output: 'export',
images: {
unoptimized: true,
},
}
module.exports = nextConfig
Your <Image> components will still work and provide the correct width, height, and alt behavior, but without automatic resizing or WebP conversion.
Alternative #1
If you want automatic image optimization without a server, use an external image CDN like Cloudinary or Imgix. Configure a custom loader in next.config.js that points to your CDN:
// next.config.js
const nextConfig = {
output: 'export',
images: {
loader: 'cloudinary',
path: 'https://res.cloudinary.com/your-cloud-name/image/upload/',
},
}
You can also write a custom loader function for any CDN:
images: {
loader: 'custom',
loaderFile: './src/imageLoader.js',
},
// src/imageLoader.js
export default function cloudinaryLoader({ src, width, quality }) {
return `https://res.cloudinary.com/demo/image/upload/w_${width},q_${quality || 75}${src}`
}
Alternative #2
For a static site where you own all the images at build time, you can pre-optimize them with a build script using sharp and use regular <img> tags (or <Image unoptimized>) to serve them:
// scripts/optimize-images.mjs
import sharp from 'sharp'
import { glob } from 'glob'
const files = await glob('public/images/**/*.{jpg,png}')
for (const file of files) {
await sharp(file)
.webp({ quality: 80 })
.toFile(file.replace(/\.(jpg|png)$/, '.webp'))
}
Then reference the .webp files in your components. This trades runtime optimization for build-time work, which is a good fit for content sites with a known image set.