Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Next.js’s Image component as a safer, optimized replacement for a raw <img>. Give it a local path, static import, or an allowed remote URL; provide intrinsic dimensions (or use fill); match sizes to the CSS layout; and choose loading, format, and caching settings for the image’s role. The result is responsive image selection, reserved layout space, and automatic optimization without writing your own srcset.

What the Next.js Image component does

next/image extends the HTML <img> element. Next.js can generate appropriately sized, modern-format responses, lazy-load images by default, and reserve the image’s aspect ratio to reduce cumulative layout shift. It does not determine your visual layout: CSS, the parent container, and the values you pass still decide how large an image appears.

Import it in either router:

import Image from 'next/image';

The same component API is used in the App Router and Pages Router, but configuration defaults can change between Next.js releases. Check the reference for the version installed in your project, especially when upgrading to Next.js 16.

Choose a source: local file, static import, or remote URL

Local files in public

Place an image at public/images/hero.jpg and reference it from the site root:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<Image src="/images/hero.jpg" alt="A dashboard on a laptop" width={1600} height={900} />

The URL is public-facing; do not include the public directory in src.

Static imports

Importing an image lets Next.js read intrinsic width, height, and (when available) blur metadata at build time:

import hero from '@/public/images/hero.jpg';

export default function Hero() {
  return <Image src={hero} alt="A dashboard on a laptop" />;
}

Static imports are convenient for assets shipped with your application. You can still override display size with CSS or explicit props.

Remote images

A remote URL must match an explicit remotePatterns entry. Because the file is not available during the build, supply width and height, or use fill:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<Image
  src="https://images.example.com/products/camera.jpg"
  alt="Mirrorless camera"
  width={1200}
  height={800}
/>

Configure only the protocol, hostname, port, pathname, and (when necessary) query pattern you actually use. The older domains setting is deprecated in favor of remotePatterns (since Next.js 14). A narrow pattern prevents your image endpoint from becoming an open proxy.

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'images.example.com',
        port: '',
        pathname: '/products/**'
      }
    ]
  }
};

module.exports = nextConfig;

Use localPatterns similarly when local optimization should be limited to particular paths. A permissive query-string rule can allow unintended source URLs, so omit query matching unless it is required.

Dimensions, fill, and layout stability

Fixed or naturally sized images

width and height describe intrinsic dimensions and preserve the source aspect ratio; they are not CSS width and height. They are required for URL sources unless you use fill. Set the rendered size with CSS:

<Image
  src="/images/avatar.png"
  alt="Profile photograph"
  width={400}
  height={400}
  className="avatar"
/>

/* app.css */
.avatar { width: 4rem; height: 4rem; border-radius: 50%; }

Images that fill a container

fill makes the generated image expand to its parent. The parent must establish positioning, and the image’s fit determines whether it crops:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<div className="card-media">
  <Image
    src="https://images.example.com/products/camera.jpg"
    alt="Mirrorless camera"
    fill
    sizes="(max-width: 700px) 100vw, 33vw"
    style={{ objectFit: 'cover' }}
  />
</div>

.card-media { position: relative; aspect-ratio: 4 / 3; }
.card-media img { object-position: center; }

Use object-fit: cover to crop into the box or contain to show the whole source (which may leave empty space).

Responsive sizing with sizes

When CSS makes an image responsive, tell the browser its likely rendered width:

<Image
  src={hero}
  alt="Analytics dashboard"
  fill
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 600px"
  style={{ objectFit: 'cover' }}
/>

Without sizes, the browser assumes 100vw. It can therefore download a much larger candidate than a two-column card needs. Write media conditions that mirror your actual breakpoints and container widths.

Loading, LCP, placeholders, and formats

Lazy, eager, and preload

The default loading mode is lazy. Use loading="eager" only when an image must start immediately. For one clearly identified above-the-fold/LCP image, use preload. Starting with Next.js 16, priority is deprecated in favor of preload; do not mark every image as preload.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<Image
  src={hero}
  alt="Product overview"
  width={1600}
  height={900}
  preload
/>

Preloading several possible LCP candidates can waste bandwidth. Prefer normal lazy loading for below-the-fold content.

Blur placeholders

A blur placeholder needs a blurDataURL. Static imports can provide blur metadata in supported cases; for a remote image, generate and provide a small data URL yourself:

<Image
  src="https://images.example.com/portrait.jpg"
  alt="Portrait"
  width={1200}
  height={1600}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..."
/>

Do not use a placeholder without a valid blur value; it will produce a runtime error.

WebP, AVIF, GIF, and SVG

WebP is the documented general-purpose choice. AVIF can produce smaller files but usually takes longer to encode, so first-request latency and cache behavior matter. Animated GIFs, very small images, and SVGs are common cases for unoptimized. SVG is not optimized by default; if you enable SVG serving, add an appropriate content-security policy and content-disposition policy for your threat model.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<Image src="/icons/animated.gif" alt="Loading" width={32} height={32} unoptimized />

Authenticated sources and custom delivery

The default optimizer does not forward authentication headers when it fetches an origin image. A URL that works in your browser with cookies or an Authorization header may fail through the optimizer. Options are:

  • Expose a narrowly scoped, signed or otherwise public image URL.
  • Use unoptimized and deliver the protected response through your own server-side route.
  • Use a custom loader or image service that performs authentication before returning an image.

Do not put long-lived secrets in a client-visible image URL. Keep remote hosts and paths constrained even when the origin is yours.

Optimization configuration and operational defaults

These are documented defaults/examples and should be checked against the Next.js version and deployment you run:

Setting Documented value or behavior Operational meaning
Default quality 75 A starting compression quality, not a measured performance guarantee.
Minimum cache TTL 4 hours (14,400 seconds) when no other directive changes it Transformed responses can remain cached; there is no built-in cache invalidation mechanism.
Maximum redirects 3 A source chain beyond this limit fails.
Maximum source response body 50 MB (50,000,000 bytes) Larger origin responses are rejected by the optimizer.

When a source image changes but its URL does not, a long cache lifetime can keep the old transformation. Change the source path (for example, add a content hash) or clear the relevant deployment/CDN cache. These defaults are not benchmark results and can differ with configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Complete examples

Responsive card component

import Image from 'next/image';

export function ProductCard({ product }) {
  return (
    <article>
      <div style={{ position: 'relative', aspectRatio: '4 / 3' }}>
        <Image
          src={product.image}
          alt={product.name}
          fill
          sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 320px"
          style={{ objectFit: 'cover' }}
        />
      </div>
      <h2>{product.name}</h2>
    </article>
  );
}

Remote URL with explicit dimensions

export default function ArticleImage() {
  return (
    <Image
      src="https://images.example.com/articles/next-image.jpg"
      alt="Code editor showing an Image component"
      width={1800}
      height={1200}
      sizes="(max-width: 900px) 100vw, 900px"
    />
  );
}
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting checklist

“Invalid src prop” or a blocked host

Cause: the URL does not match remotePatterns (including protocol, port, pathname, or query). Fix: add the narrow pattern you need, restart the development server, and verify the final URL.

Image is stretched or layout shifts

Cause: incorrect intrinsic dimensions or CSS that overrides only one axis. Fix: use the source aspect ratio for width/height, then set both CSS dimensions or use a positioned fill parent with an explicit aspect ratio.

A card downloads an unnecessarily large file

Cause: missing or inaccurate sizes. Fix: describe the card’s real width at each breakpoint.

The remote image returns 401/403

Cause: optimizer fetches do not forward your authentication headers. Fix: use a public signed source, a server-side proxy, unoptimized, or a custom loader.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Updated source is not visible

Cause: a transformed response remains in cache. Fix: version the source URL or clear the deployment/CDN cache; there is no general image-cache invalidation API.

SVG or animated content behaves unexpectedly

Cause: SVG is not optimized by default and animation may be altered by processing. Fix: serve these assets with an appropriate unoptimized strategy and apply SVG security headers when enabling SVG handling.

Or skip the browser setup

If you need screenshots of a page that demonstrates your Next.js images, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one request. Its cleaner capture accepts cookie banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. It also provides an MCP server for Claude, Cursor, and other MCP clients with take_screenshot, get_page_info, and capture_pdf.

cURL (see the ScreenshotNeo documentation):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://nextjs.org -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://nextjs.org"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://nextjs.org' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Every feature is included on every plan: 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I use a data URL as the Image source?

The documented source choices are local paths, static imports, and remote absolute URLs. For unusual data or generated content, render it through an appropriate route or use an unoptimized image strategy rather than assuming every data URL is accepted.

Does Image automatically improve search rankings?

The component supports technical practices such as dimensions, responsive candidates, and modern formats, but the documentation does not establish a specific SEO or ranking increase.

Should every image use preload?

No. Reserve preload for one clearly identified above-the-fold or LCP candidate; normal images should remain lazy or use the default loading behavior.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.