R
Rishtaara
Next.js: Zero to Full-Stack
Lesson 7 of 42Article17 min

Optimizing Fonts and Images

next/font loads fonts in a way that reduces layout shift and avoids extra network round-trips for common Google fonts.

Optimize fonts with next/font

next/font loads fonts in a way that reduces layout shift and avoids extra network round-trips for common Google fonts.

You import a font in the root layout, apply its className to body or a wrapper, and Next hosts the files efficiently.

Real-life example: next/font is like storing school uniforms in the building locker — students dress on site instead of waiting for a delivery truck every morning.

Google font in app/layout.tsx
import { Inter } from "next/font/google";
import type { ReactNode } from "react";
import "./globals.css";

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

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

Custom local fonts

For brand fonts, place files under a folder like app/fonts/ or src/app/fonts/ and use localFont from next/font/local.

Real-life example: A local font is your family recipe book on the shelf — you already own it, so you do not order it from a store each time guests arrive.

Local font with next/font/local
import localFont from "next/font/local";

const brand = localFont({
  src: "./fonts/BrandSans.woff2",
  variable: "--font-brand",
  display: "swap",
});

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={brand.variable}>
      <body>{children}</body>
    </html>
  );
}

Optimize images with next/image

Use the Image component from next/image instead of a plain img tag when you can. It helps with resizing, lazy loading, and modern formats.

Images in public/ are referenced by path string. Images imported from the file system get width and height automatically.

Real-life example: next/image is a smart photo lab — it prints the right size print for a phone screen or a billboard instead of handing everyone the same huge poster.

Tip: Always set meaningful alt text. For above-the-fold LCP images, consider priority so the browser loads them sooner.
Image from public/ vs imported file
import Image from "next/image";
import heroPic from "@/assets/hero.jpg";

export default function Gallery() {
  return (
    <section>
      {/* From public/logo.png → URL "/logo.png" */}
      <Image
        src="/logo.png"
        alt="Rishtaara logo"
        width={120}
        height={40}
        priority
      />

      {/* Imported image — dimensions inferred */}
      <Image src={heroPic} alt="Course hero" placeholder="blur" />
    </section>
  );
}

Rendering modes reminder

Fonts and images work across static and dynamic pages. Next.js can still pre-render shells and stream the rest for faster first paint.

Real-life example: Optimized assets are pre-chopped vegetables — whether you cook for one guest (SSR) or meal-prep for the week (SSG), prep work saves time.

Rendering strategies in Next.js