Harness-engineering next-parallel-intercepting-routes
Next.js Parallel and Intercepting Routes
git clone https://github.com/Intense-Visions/harness-engineering
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/codex/next-parallel-intercepting-routes" ~/.claude/skills/intense-visions-harness-engineering-next-parallel-intercepting-routes-a482de && rm -rf "$T"
agents/skills/codex/next-parallel-intercepting-routes/SKILL.mdNext.js Parallel and Intercepting Routes
Render multiple pages simultaneously in one layout and intercept routes for modal patterns
When to Use
- Building modal UIs that show a page in an overlay while keeping the background page visible
- Displaying different views in side-by-side slots within a layout (dashboard tabs, split views)
- Implementing photo gallery lightbox patterns where direct URL access shows the full page
- Creating conditional UI based on authentication or application state within a layout
- Building tabbed interfaces where each tab has its own URL and loading/error state
Instructions
- Create parallel route slots with
folders inside a layout's directory — each slot becomes a prop in@slotName/
.layout.tsx - Define
in each slot directory to render when the slot has no matching route — prevents the slot from 404ing.default.tsx - Intercept a route by prefixing its folder with
(same level),(.)
(one level up),(..)
(two levels up), or(..)(..)
(root).(...) - Pair an intercepting route with a parallel slot: clicking a link shows the modal (intercepting route in the
slot); navigating directly or refreshing shows the full page.@modal - Use
or a Link to close modals — do not manage modal open state in React state when URLs are involved.useRouter().back() - Keep
returningdefault.tsx
for modal slots that have no default state (slot is empty when no modal is open).null
app/ layout.tsx ← receives @modal as a prop @modal/ (.)photos/[id]/ page.tsx ← renders as modal when navigating from /photos default.tsx ← returns null (no modal by default) photos/ [id]/ page.tsx ← renders as full page on direct URL access or refresh page.tsx ← photo grid
// app/layout.tsx — parallel route slot as a prop export default function RootLayout({ children, modal, }: { children: React.ReactNode; modal: React.ReactNode; }) { return ( <html> <body> {children} {modal} {/* renders modal content or null */} </body> </html> ); } // app/@modal/(.)photos/[id]/page.tsx — intercepting route modal import { Modal } from '@/components/modal'; export default function PhotoModal({ params }: { params: { id: string } }) { return ( <Modal> <Photo id={params.id} /> </Modal> ); }
Details
Parallel routes and intercepting routes solve a specific UX problem: showing a resource at two different levels of UI (modal vs full page) depending on navigation context, while keeping the URL meaningful.
Soft vs hard navigation: When a user clicks a
<Link> to /photos/42 from within the app, Next.js performs a soft navigation and renders the intercepting route (@modal/(.)photos/[id]) inside the modal slot. When the user refreshes or navigates directly to /photos/42, Next.js performs a hard navigation and renders the actual photos/[id]/page.tsx as a full page. The URL is identical in both cases.
is mandatory: Without default.tsx
default.tsx in each parallel slot, Next.js throws a 404 when a route renders but no matching slot exists. The default file specifies what to render in that slot when it has no active content.
Slot naming: Slot folder names (e.g.,
@modal, @sidebar, @team) become prop names in the parent layout. The children prop is equivalent to an implicit @children slot.
Intercepting route notation:
(.) matches routes at the same route segment level (most common for modals). (..) goes one segment up. (...) matches from the app root. The notation mirrors relative filesystem path traversal.
Trade-offs: Parallel routes add directory nesting. Complex slot combinations can be hard to debug — use the Next.js DevTools panel to inspect active slots. Avoid over-using this pattern; simple state-based modals are sufficient when URL-sharing is not a requirement.
Source
https://nextjs.org/docs/app/building-your-application/routing/parallel-routes
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.