Technology · Next.js
Next.js Image Optimization
Optimize images in Next.js using the Image component for better performance.
TL;DR
- 01Use next/image instead of img tags for automatic optimization.
- 02Lazy loading and responsive resizing happen automatically.
- 03Specify width and height to prevent layout shift and improve scores.
Basic Image Component
- Import and use Image component from next/image.
import Image from 'next/image'; export default function Hero() { return ( <Image src="/hero.jpg" alt="Hero image" width={1200} height={600} /> ); } - Always specify width and height for best performance.
- alt text is required for accessibility.
- Images are served as WebP automatically for supported browsers.
- Use the placeholder prop to show a blur while the image loads.
import Image from 'next/image'; import heroImg from '@/public/hero.jpg'; <Image src={heroImg} alt="Hero" placeholder="blur" // works with static imports automatically /> - Use blurDataURL to provide a custom blur placeholder for external images.
<Image src="https://cdn.example.com/photo.jpg" alt="Photo" width={800} height={600} placeholder="blur" blurDataURL="data:image/png;base64,..." />
Local vs External Images
- Local images in public folder.
import Image from 'next/image'; import heroImage from '@/public/hero.jpg'; <Image src={heroImage} alt="Hero" /> - External images need domain configuration.
// next.config.js module.exports = { images: { domains: ['cdn.example.com', 'images.example.com'] } }; - Use remotePatterns instead of domains for more precise allowlisting.
module.exports = { images: { remotePatterns: [{ hostname: "cdn.example.com", pathname: "/uploads/**" }] } }; - Static imports infer width, height, and enable blur placeholder automatically.
import logo from '@/public/logo.png'; // width/height inferred <Image src={logo} alt="Logo" /> - Use unoptimized to skip optimization for SVGs or animated GIFs.
<Image src="/icon.svg" alt="Icon" width={32} height={32} unoptimized />
Responsive Images
- Use fill prop for responsive sizing.
<Image src="/hero.jpg" alt="Hero" fill style={{ objectFit: 'cover' }} /> - Specify sizes for responsive images.
<Image src="/card.jpg" alt="Card" width={300} height={200} sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" /> - The fill image must be inside a positioned container.
<div style={{ position: "relative", width: "100%", height: "400px" }}> <Image src="/banner.jpg" alt="Banner" fill style={{ objectFit: "cover" }} /> </div> - Use objectPosition to control the focal point of a filled image.
<Image src="/portrait.jpg" alt="Portrait" fill style={{ objectFit: "cover", objectPosition: "top center" }} /> - Use sizes to help the browser choose the right srcset variant.
<Image src="/hero.jpg" alt="Hero" fill sizes="100vw" // full-width image />
Lazy Loading
- Lazy loading is automatic by default.
<Image src="/below-fold.jpg" alt="Below fold image" width={800} height={600} loading="lazy" // Default behavior /> - Disable lazy loading for above-fold images.
<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority // Load immediately /> - Use priority on the largest above-fold image to improve LCP score.
- Eager loading loads the image immediately without waiting for viewport.
<Image src="/logo.png" alt="Logo" width={120} height={40} loading="eager" // Don't defer /> - Images outside the viewport are deferred until the user scrolls near them.
<Image src="/infographic.png" alt="Infographic" width={800} height={600} // loading="lazy" is the default — no need to set it explicitly />
Image Quality
- Control image quality with quality prop.
<Image src="/photo.jpg" alt="Photo" width={500} height={300} quality={80} // 1-100, default 75 /> - Format automatically optimized for browser.
// Automatically serves WebP to browsers that support it <Image src="/photo.jpg" alt="Photo" width={500} height={300} /> - Lower quality to 60–70 for hero images that cover large areas.
<Image src="/hero.jpg" alt="Hero" fill quality={65} /> // Good visual quality at smaller file sizes for large backgrounds - Configure global image quality defaults in next.config.js.
module.exports = { images: { qualities: [75, 90], // only generate these quality variants minimumCacheTTL: 86400 // cache optimized images for 1 day } }; - Use quality={100} for images where accuracy matters like product photos.
<Image src="/product-detail.png" alt="Product" width={600} height={600} quality={100} />
Tip: Always specify width and height — it prevents layout shift and improves performance significantly.
Warning: Don't use Image for images that change dimensions frequently — use regular img tags instead.