javascript 37 lines · 6 steps

An intercepted photo modal route in Next.js

An async server component fetches a photo by id, sets its page metadata, and renders it inside a modal.

Explained by highlit
1import { notFound } from 'next/navigation'
2import { getPhotoById } from '@/lib/photos'
3import Modal from '@/components/modal'
4import Image from 'next/image'
5 
6export async function generateMetadata({ params }) {
7 const { id } = await params
8 const photo = await getPhotoById(id)
9 if (!photo) return {}
10 return { title: photo.title }
11}
12 
13export default async function PhotoModal({ params }) {
14 const { id } = await params
15 const photo = await getPhotoById(id)
16 
17 if (!photo) notFound()
18 
19 return (
20 <Modal>
21 <figure className="photo-modal">
22 <Image
23 src={photo.url}
24 alt={photo.title}
25 width={photo.width}
26 height={photo.height}
27 sizes="(max-width: 768px) 100vw, 768px"
28 priority
29 />
30 <figcaption>
31 <h2>{photo.title}</h2>
32 <p>by {photo.author}</p>
33 </figcaption>
34 </figure>
35 </Modal>
36 )
37}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Async server components can await params and fetch data directly before rendering.
  2. 2generateMetadata and the page component share the same data-fetching logic to stay consistent.
  3. 3Calling notFound() short-circuits rendering into the framework's 404 handling for missing records.

Related explainers

Share this explainer

Here's the card — post it anywhere.

An intercepted photo modal route in Next.js — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code