← All lessons
Lesson 17 · Advanced

Image & Font Optimization

Use the built-in `<Image>` and `next/font` to avoid layout shift, ship modern formats and self-host fonts.

next/image

Replace <img> with the Next.js <Image> component. It automatically lazy-loads, serves modern formats like AVIF/WebP, and reserves space so you don't get layout shift.

import Image from "next/image";

export default function Hero() {
  return (
    <Image
      src="/hero.jpg"
      width={1200}
      height={600}
      alt="A bright workspace"
      priority
    />
  );
}
  • **width and height** are required so Next.js can reserve space — except for fill.
  • **priority** preloads the image — use it for the hero/LCP image, not for everything.
  • **sizes** tells the browser how big the image will be on different screens, so it can pick the right source.
  • Remote images need their host whitelisted in next.config.mjs under images.remotePatterns.

Filling a parent

When you don't know the image's size, use fill with a sized parent:

<div style={{ position: "relative", width: "100%", height: 400 }}>
  <Image src="/cover.jpg" alt="cover" fill style={{ objectFit: "cover" }} />
</div>

next/font

Custom fonts are loaded at build time and served from your own domain — no extra network call to Google, no FOUT.

// app/layout.js
import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"], display: "swap" });

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

The result is one CSS class you can apply anywhere. The font CSS, the font file, and font-display behavior are all handled for you.

Local fonts

import localFont from "next/font/local";

const display = localFont({
  src: "./fonts/Display-Variable.woff2",
  display: "swap",
  variable: "--font-display",
});
Note: Both next/image and next/font rely on Next.js's build pipeline. They cost nothing to add and tend to win an audit category each.

Try it

Replace this raw <img> tag with next/image. Use width 800 and height 450.

Need a hint?

Import Image from next/image and supply width/height props.

Quiz

Pick the best answer. You only get one shot per question.

1. Why does `<Image>` require `width` and `height`?

2. When should you set `priority` on an `<Image>`?

3. What does `next/font` give you over a `<link>` to Google Fonts?