Next.js Image Component Optimization Errors and How to Fix Them
Troubleshooting the Next.js Image component including layout shift, missing sizes prop, and external image domain errors
Next.js Image Component Optimization Errors and How to Fix Them
Introduction
The next/image component is one of Next.js's most powerful features. It automatically optimizes images, prevents layout shift, and serves modern formats like WebP and AVIF. However, developers frequently encounter errors when using it, especially with external images, dynamic sizing, and layout configurations.
While working on an e-commerce project last year, I ran into a cascade of Image-related errors that took me two full days to resolve. This post documents every issue I encountered and the solutions that worked.
Environment
- OS: Windows 11
- Node.js: v20.10.0
- Next.js: 14.0.4
- React: 18.2.0
Problem
When using the next/image component, I encountered multiple errors in the browser console and during build:
Error: Invalid src prop (https://images.unsplash.com/photo-xxx) on `next/image`,
hostname "images.unsplash.com" is not configured under images in next.config.jsWarning: Image with src "/_next/static/media/hero.png" has unused properties
supplied. Make sure to remove the "layout" and "objectFit" properties.CLS detected: layout shift caused by image component without width/heightDuring the build process:
Error: Image Optimization using the default loader is not compatible with `export`.
Please use `next export` with a custom loader or switch to the `node` runtime.Analysis
There were four distinct issues at play:
1. Missing remote image domain configuration. Next.js requires explicit allowlisting of external image domains for security.
2. Deprecated props being used. The layout and objectFit props were replaced by fill and CSS-based approaches in Next.js 13+.
3. Missing width/height causing layout shift. When neither width, height, nor fill is specified, the browser cannot reserve space for the image, causing Cumulative Layout Shift (CLS).
4. Static export incompatibility. The default image optimizer requires a Node.js server and cannot work with next export.
Solution
Fix 1: Configure remote image domains
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.unsplash.com',
},
{
protocol: 'https',
hostname: 'cdn.example.com',
pathname: '/products/**',
},
],
formats: ['image/avif', 'image/webp'],
},
}
module.exports = nextConfigFix 2: Use the modern Image component API
// BEFORE (deprecated)
import Image from 'next/image'
// AFTER (correct)
import Image from 'next/image'
Fix 3: Always provide width and height for non-fill images
// Static images - provide explicit dimensions
import Image from 'next/image'
// Responsive images - use the fill prop with a container
Fix 4: Use a custom loader for static export
// lib/imageLoader.ts
export default function cloudinaryLoader({
src,
width,
quality,
}: {
src: string
width: number
quality?: number
}) {
const params = [
`f_auto`,
`c_limit`,
`w_${width}`,
`q_${quality || 'auto'}`,
]
return `https://res.cloudinary.com/demo/image/upload/${params.join(',')}${src}`
}// components/OptimizedImage.tsx
'use client'
import Image from 'next/image'
import cloudinaryLoader from '@/lib/imageLoader'
export function OptimizedImage({ src, alt }: { src: string; alt: string }) {
return (
)
}Fix 5: Prevent CLS with aspect ratio containers
// components/ResponsiveImage.tsx
import Image from 'next/image'
interface ResponsiveImageProps {
src: string
alt: string
aspectRatio?: number // width / height, default 16/9
}
export function ResponsiveImage({
src,
alt,
aspectRatio = 16 / 9,
}: ResponsiveImageProps) {
return (
)
}Lessons Learned
Always specify
sizeswhen usingfill. Without it, Next.js cannot serve appropriately sized images for different viewports, negating the performance benefits.Use
priorityfor above-the-fold images. This adds a preload link tag, preventing layout shift and improving Largest Contentful Paint (LCP).Prefer
remotePatternsoverdomains. Thedomainsoption is deprecated and will be removed in future versions.Test image performance with Lighthouse. Aim for a CLS score of 0.0 or very close to it.
Consider using a CDN for image-heavy sites. Cloudinary, imgix, or Vercel Image Optimization can handle more formats and transformations than the built-in optimizer.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.