Photo Modal with Intercepted Routes
Hard · Routing
Instagram-style photo links: clicking a photo in the feed opens it in a modal over the feed and changes the URL to /photos/<id>, but opening that URL directly (refresh, shared link) shows a full photo page.
Next.js builds this with two features. A parallel route slot app/@modal renders next to the page, and an intercepting route app/@modal/(.)photos/[id]/page.tsx catches soft navigations (Link clicks) to /photos/[id] and renders the modal there, while app/photos/[id]/page.tsx handles hard loads. The mock router here has no file system, so model it in one component: remember in state that the user arrived through a Link click (a soft navigation).
- At / render the feed: <ul className="feed"> with a <Link className="thumb" href="/photos/<id>"> per photo (text = title).
- After a thumbnail click, keep the feed and show <div role="dialog" className="modal"> with an <h2> title, a <Link className="next">Next</Link> and a <button>Close</button>.
- Next opens the following photo (after the last one comes the first) with <Link replace>, so the modal does not stack history entries.
- Close calls router.back(): the modal URL is a single history entry, so going back returns to the feed exactly as the user left it.
- A hard load of /photos/<id> (navigate() in the tests, like typing the URL) shows only <main className="photo-page"> with an <h1> title and a <Link href="/">Back to feed</Link>. No feed, no dialog.
- An unknown id on a hard load shows <h1>Photo not found</h1> (with the same link).