Next.js cookbook · Beginner

Optimize images with next/image

Serve responsive, lazy-loaded images in modern formats without layout shift, including from a CMS.

Approach

Use next/image with explicit width/height (or fill + sizes) to prevent layout shift, sizes to download appropriately sized files, and priority (preload) for the LCP hero image only. Allow remote hosts with images.remotePatterns.

Solution

// next.config.ts
import type { NextConfig } from "next";
const config: NextConfig = {
  images: {
    remotePatterns: [{ protocol: "https", hostname: "cdn.examplecms.com", pathname: "/assets/**" }],
    formats: ["image/avif", "image/webp"],
  },
};
export default config;

// app/page.tsx
import Image from "next/image";
import hero from "./hero.jpg";                     // static import: width/height/blur inferred

export default function Home({ products }: { products: Product[] }) {
  return (
    <>
      <Image src={hero} alt="Team working together" priority placeholder="blur" sizes="100vw" style={{ width: "100%", height: "auto" }} />
      <ul className="grid">
        {products.map((p) => (
          <li key={p.id} style={{ position: "relative", aspectRatio: "1 / 1" }}>
            <Image src={p.imageUrl} alt={p.name} fill sizes="(max-width: 768px) 50vw, 25vw" style={{ objectFit: "cover" }} />
          </li>
        ))}
      </ul>
    </>
  );
}

Pitfalls

  • priority on many images (defeats prioritization).
  • fill without a sized, positioned parent.
  • Missing sizes with fill, so the browser downloads oversized images.

Variations

  • A custom loader for image CDNs (Cloudinary, Imgix).
  • Unoptimized images for already-optimized SVGs.

Further reading: Next.js: Image component

Reference: https://nextjs.org/docs/app/api-reference/components/image

More Next.js recipes