Next.js

Next.js Parallel Routes👨‍💻

Parallel routes let you render multiple pages simultaneously inside a single layout, each in its own named slot. The layout receives each slot as a prop and decides where (and whether) to render it. The classic example is a dashboard where an analytics panel and a recent activity feed load independently -- if one is slow or errors out, the other still works.

The real power shows up when you combine parallel routes with intercepting routes. That combination is how you build modals that have their own URL, survive a page refresh, and close properly with the back button. Think of an Instagram-style photo overlay or a login modal that can also be accessed as a standalone page. Without parallel routes, you end up managing modal state manually and losing the URL entirely.

Key Takeaways

  • 1Named slots use the `@folder` convention (e.g. `@analytics`, `@modal`) and are passed as props to the parent layout -- they do not affect the URL
  • 2The `children` prop is an implicit slot equivalent to `@children/page.tsx` -- you do not need to create an `@children` folder
  • 3Every slot needs a `default.tsx` fallback for hard navigations (full page refresh), otherwise Next.js returns an error because it cannot recover the slot's active state
  • 4Slots are streamed independently, so each one can have its own `loading.tsx` and `error.tsx` without blocking the others
  • 5Combining a parallel slot with intercepting routes (`(.)`, `(..)`) is the standard pattern for URL-preserving modals that degrade gracefully to a full page
  • 6Parallel routes enable conditional rendering at the layout level -- render different slots based on auth state, user role, or feature flags without client-side JavaScript

Master next.js parallel routes

Take the Next.js Full-Stack course with hands-on lessons and challenges.

Examples

Dashboard with independent analytics and activity slots

tsx

Each slot loads independently. If the analytics query takes 3 seconds, the activity feed and main content render immediately. Each slot has its own loading.tsx, so the user sees targeted skeleton states instead of a single spinner for the whole page.

default.tsx -- the file you always forget

tsx

When a user refreshes the page, Next.js cannot recover slot state from the client router. Without default.tsx, unmatched slots trigger an error. Return null to hide the slot, or re-export the page component to show a sensible fallback. You also need a default.tsx for the implicit children slot.

Photo modal with intercepting routes (Instagram pattern)

tsx

Clicking a photo thumbnail triggers a soft navigation. Next.js intercepts the route and renders the modal slot instead of navigating away. The URL updates to /gallery/123, so the link is shareable. A hard refresh loads app/gallery/[id]/page.tsx as a full page. The (..) convention is based on route segments, not file-system levels -- @modal is a slot, not a segment, so (.) is correct here.

Conditional slot rendering based on auth

tsx

The layout is a Server Component, so the auth check runs on the server with zero client JS. The admin slot is never sent to the browser for regular users -- it is not just hidden with CSS, it is never rendered at all. This is a clean separation compared to a single page with role-based conditional blocks scattered everywhere.

Tab navigation inside a slot

tsx

Adding a layout inside a slot creates an independent navigation context. The tab links change what renders in @analytics without affecting the main content or other slots. The rest of the dashboard stays exactly where it is -- no full page transition, no re-fetching data in other panels.

Common Mistakes

Mistake:

Forgetting `default.tsx` in every slot (and for the implicit children slot) -- leading to errors on page refresh

Fix:

Add a `default.tsx` to every `@slot` folder and to the route segment itself (for the children slot). Return `null` if the slot should be empty, or re-export the main page component if you want to show a fallback. Test by navigating to a sub-route and then refreshing the browser.

Mistake:

Thinking the `(..)` intercepting convention follows file-system paths -- and miscounting levels because of `@slot` folders

Fix:

The convention is based on route segments, not file-system directories. Slot folders like `@modal` are not route segments, so they are skipped when counting levels. `(.)` inside `@modal` matches the same route level as the parent, not one level down.

Mistake:

Using parallel routes for simple layout composition that nested layouts already solve -- adding unnecessary complexity

Fix:

If your content sections do not need independent loading states, independent error boundaries, or conditional rendering based on server-side logic, use regular nested layouts and component composition instead. Parallel routes add real file-system overhead.

Mistake:

Not providing a catch-all page (`[...catchAll]/page.tsx`) in modal slots, causing the modal to persist when navigating to unrelated routes

Fix:

Add `@modal/[...catchAll]/page.tsx` that returns `null`. Without it, the slot stays visible during client-side navigation to routes that do not match the slot, because Next.js preserves the last matched state.

Best Practices

  • Always test parallel routes with both soft navigation (clicking links) and hard navigation (browser refresh) -- they behave differently, and default.tsx issues only surface on refresh
  • Keep slot contents as Server Components by default. Pass interactive pieces as children to thin Client Component wrappers. This keeps your slots streamable and avoids shipping unnecessary JS.
  • Use independent `loading.tsx` and `error.tsx` files inside each slot to give users targeted feedback instead of a full-page spinner or error screen
  • Combine parallel routes with intercepting routes only for the modal pattern (shareable URL + overlay). For simple dialogs triggered by a button, a regular client-side modal with state is simpler and more appropriate.
  • When building conditional layouts (admin vs user), remember that both slot trees are defined in the file system but only the selected one is rendered and sent to the client -- use this for security-sensitive UI separation

Summary

Parallel routes split a single layout into independently rendered slots using the `@folder` convention. Each slot loads, errors, and navigates on its own. The three patterns worth learning are: dashboard panels with independent streaming, modals that combine parallel slots with intercepting routes for URL-preserving overlays, and conditional rendering based on server-side auth checks. The critical implementation detail is `default.tsx` -- every slot needs one, and the implicit children slot does too, or your app breaks on hard navigation. Parallel routes are powerful, but they add file-system complexity. Reach for them when you genuinely need independent loading states, route interception for modals, or server-side conditional slot rendering. For everything else, nested layouts and component composition are simpler.

Practice Next.js with hands-on challenges

Learn next.js parallel routes hands-on in your IDE

Interactive lessons and challenges on Stanza, practice in VS Code, Cursor, or the web.

Related Concepts

Related Cheatsheets

Master Next.js with Stanza

Interactive lessons and challenges, right in your code editor.

Check the free courses. No credit card.