Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🎨 Styling, Images & Fonts  ·  Lesson 17

next/image & next/font

Why images and fonts matter

Images are usually 70% of a page's weight. Fonts loaded late cause text to "jump". Both hurt Google's Core Web Vitals (LCP and CLS) — and therefore your ranking and click-through rate. Next.js gives two built-in tools: next/image and next/font.

Plain <img> + Google Fonts link

  • Full 2 MB PNG on phones
  • All images load at once
  • Layout jumps when image arrives
  • Extra request to fonts.googleapis.com

next/image + next/font

  • Resized WebP/AVIF ~60 KB
  • Lazy-loaded below the fold
  • Space reserved → no jump
  • Font self-hosted, zero shift
Same page, very different speed

The <Image> component

JSX – components/CourseCard.jsx
// components/CourseCard.jsx  (from the EduSite project)
import Image from 'next/image'

<Image
  src={course.image}            // "/images/nextjs.png" from public/
  alt={course.title}            // always describe the image (SEO + accessibility)
  width={600}
  height={338}
  sizes="(max-width: 700px) 100vw, 360px"
/>

width, height, sizes, priority

PropMeaning
width / heightIntrinsic size (aspect ratio). Prevents layout shift.
sizesHow wide the image is shown at each screen size, so the browser downloads the right file.
priorityPreload — only for the main above-the-fold image.
quality1–100, default 75 (must be in images.qualities).
placeholder="blur"Shows a blurred preview while loading.
JSX – hero image with priority
// app/courses/[slug]/page.jsx — the big image at the top
<Image
  src={course.image}
  alt={course.title}
  width={1200}
  height={675}
  priority                      // above the fold → load first (better LCP)
  quality={90}
  sizes="(max-width: 700px) 100vw, 560px"
  style={{ borderRadius: 16 }}
/>
JSX – static import with blur placeholder
// Static import: width/height and blur placeholder detected automatically
import heroPic from '@/public/images/hero.png'

<Image src={heroPic} alt="Students learning to code" placeholder="blur" priority />

What next/image does for you

hero.png2.1 MB/_next/imageresize to 640wWebP≈ 70 KBcachenext requests instant
Automatic resize, modern format and caching
EduSite home page with optimized next/image hero
EduSite hero and course images all use next/image

Remote images & config

JS – next.config.mjs
// next.config.mjs
const nextConfig = {
  images: {
    qualities: [75, 90],          // Next.js 16: allowed quality values
    remotePatterns: [
      { protocol: 'https', hostname: 'cdn.example.com', pathname: '/uploads/**' },
    ],
  },
}
export default nextConfig

// now this works:
<Image src="https://cdn.example.com/uploads/shoe.jpg" alt="Shoe" width={400} height={400} />

fill mode for cover images

When you do not know the size (a banner that stretches), use fill. The parent must have position: relative and a height.

JSX – fill
<div style={{ position: 'relative', height: 280 }}>
  <Image src="/images/hero.png" alt="Classroom" fill
         style={{ objectFit: 'cover' }} sizes="100vw" />
</div>

next/font: Google fonts

JSX – app/layout.jsx
// app/layout.jsx
import { Poppins } from 'next/font/google'

const poppins = Poppins({ subsets: ['latin'], weight: ['400', '700'], display: 'swap' })

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

Local font files

JSX + CSS – local font
// app/layout.jsx  (EduSite uses a local Inter file)
import localFont from 'next/font/local'

const inter = localFont({
  src: './fonts/Inter.woff2',
  variable: '--font-inter',     // exposes a CSS variable
  display: 'swap',
})

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

/* globals.css */
body { font-family: var(--font-inter), system-ui, sans-serif; }
npm run buildYour serverBrowserdownload & subset fontInter.woff2 in /_next/staticGET pageHTML + <link rel=preload font>text renders with correct metrics
Fonts served from your own domain

Common mistakes

  • Empty or missing alt on meaningful images → bad for SEO and screen readers.
  • priority on every image → nothing is a priority any more; use it on 1–2 images.
  • Remote image without remotePatterns → error "hostname is not configured".
  • quality={90} without adding 90 to images.qualities in Next.js 16 → error.
  • fill without a positioned parent → image covers the whole page.

Summary

  • <Image> resizes, converts to WebP/AVIF, lazy-loads and prevents layout shift.
  • Give width/height (or fill), a good alt, correct sizes; priority for the hero.
  • next/font self-hosts Google or local fonts with zero layout shift.
✅ Practice

Replace every <img> in your project with <Image>, add a Google font with next/font, then run Lighthouse in Chrome DevTools and compare the Performance score.

Frequently Asked Questions

Why does next/image require width and height?
They let the browser reserve the right space before the image loads, which prevents layout shift (CLS). With fill mode, the parent box provides the size instead.
When should I use priority?
Only for the main image visible above the fold, usually the hero or product photo. It preloads the image and improves Largest Contentful Paint (LCP).
Does next/font contact Google at runtime?
No. Fonts are downloaded at build time and served from your own domain, which is faster and better for privacy.
What is images.qualities in Next.js 16?
Next.js 16 only allows the quality values listed in images.qualities (default [75]). If you use quality={90}, add 90 to that list in next.config.
← Next.js Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicServer vs Client Components Your progress: 17 / 37 (46%) · Lesson 18 / 37 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free