Optimize images in Next.js using the Image component for better performance.
import Image from 'next/image';
export default function Hero() {
return (
<Image
src="/hero.jpg"
alt="Hero image"
width={1200}
height={600}
/>
);
}import Image from 'next/image';
import heroImg from '@/public/hero.jpg';
<Image
src={heroImg}
alt="Hero"
placeholder="blur" // works with static imports automatically
/><Image
src="https://cdn.example.com/photo.jpg"
alt="Photo"
width={800}
height={600}
placeholder="blur"
blurDataURL="data:image/png;base64,..."
/>import Image from 'next/image';
import heroImage from '@/public/hero.jpg';
<Image src={heroImage} alt="Hero" />// next.config.js
module.exports = {
images: {
remotePatterns: [{ hostname: "cdn.example.com", pathname: "/uploads/**" }]
}
};module.exports = {
images: {
remotePatterns: [
{ hostname: "cdn.example.com" },
{ hostname: "images.example.com", protocol: "https" }
]
}
};import logo from '@/public/logo.png'; // width/height inferred
<Image src={logo} alt="Logo" /><Image
src="/icon.svg"
alt="Icon"
width={32}
height={32}
unoptimized
/><Image
src="/hero.jpg"
alt="Hero"
fill
style={{ objectFit: 'cover' }}
/><Image
src="/card.jpg"
alt="Card"
width={300}
height={200}
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
/><div style={{ position: "relative", width: "100%", height: "400px" }}>
<Image src="/banner.jpg" alt="Banner" fill style={{ objectFit: "cover" }} />
</div><Image
src="/portrait.jpg"
alt="Portrait"
fill
style={{ objectFit: "cover", objectPosition: "top center" }}
/><Image
src="/hero.jpg"
alt="Hero"
fill
sizes="100vw" // full-width image
/><Image
src="/below-fold.jpg"
alt="Below fold image"
width={800}
height={600}
loading="lazy" // Default behavior
/><Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // Load immediately
/><Image
src="/logo.png"
alt="Logo"
width={120}
height={40}
loading="eager" // Don't defer
/><Image
src="/infographic.png"
alt="Infographic"
width={800}
height={600}
// loading="lazy" is the default — no need to set it explicitly
/><Image
src="/photo.jpg"
alt="Photo"
width={500}
height={300}
quality={80} // 1-100, default 75
/>// Automatically serves WebP to browsers that support it
<Image
src="/photo.jpg"
alt="Photo"
width={500}
height={300}
/><Image src="/hero.jpg" alt="Hero" fill quality={65} />
// Good visual quality at smaller file sizes for large backgroundsmodule.exports = {
images: {
qualities: [75, 90], // only generate these quality variants
minimumCacheTTL: 86400 // cache optimized images for 1 day
}
};<Image
src="/product-detail.png"
alt="Product"
width={600}
height={600}
quality={100}
/>Yes — add the external hostname to the remotePatterns array in next.config.js under the images key. Without this, Next.js will block external image requests for security reasons.
Use the fill prop on the Image component and set the parent element to position: relative with a defined size. Then use sizes prop to hint the browser about the rendered width at different breakpoints for optimal file delivery.
Missing or incorrect sizes prop is the most common culprit — without it, Next.js serves a full-resolution image regardless of display size. Define sizes to match your layout breakpoints so the right image size is requested.
The default quality is 75, which balances file size and visual fidelity for most cases. Pass quality={90} or higher only for images where compression artifacts are noticeable, such as product photos or hero images.
Add the priority prop to images that appear above the fold — like hero banners or LCP candidates — so they are eagerly fetched instead of deferred. Only use it for the first few visible images; overusing it defeats the performance benefit of lazy loading.