Next.js parallel routes let a single layout render more than one page at the same time, each one navigable on its own. Create named slots with an @ prefix, and Next.js passes each slot to the shared layout as a separate prop.
// app/dashboard/layout.tsx
type Props = { children: React.ReactNode; analytics: React.ReactNode; team: React.ReactNode };
export default function Layout({ children, analytics, team }: Props) {
return <>{children}{team}{analytics}</>;
}For a folder structure with @analytics and @team slots beside the regular page file, the layout renders all three together. Visiting /dashboard shows the main page plus both slot pages at once, each with its own file inside its own slot folder.
Slots are not route segments
A slot name never becomes part of the URL. A page inside a slot named analytics still resolves to /dashboard, not /dashboard/analytics. The @ prefix only tells Next.js how to pass that folder's content to the layout, the same way children is an implicit slot for the regular page file.
This matters because it changes how you think about the folder tree. Adding a slot never grows the site's URL structure, it only grows the number of independent view regions a single URL can render at once. A dashboard with three slots still has one address, even though three separate page trees render underneath it.
default.js and hard navigation
On a client-side navigation, Next.js keeps each slot's last active subpage even if the new URL does not match it. On a full page reload, Next.js cannot recover that state, so it renders each slot's default file instead.
// app/dashboard/@analytics/default.tsx
export default function Default() {
return null;
}Without a default file, a named slot with no matching route for the current URL fails the build instead of rendering silently, so Next.js requires one to exist for every named slot. Adding a default file that returns null is usually enough for a slot that should simply stay empty until its own route is visited directly. The full rules for this file, including how to restore the older 404 fallback deliberately, are covered in default.js explained.
Independent loading and error states
Because each slot renders its own page tree, each one can define its own loading file and error file, exactly as a regular route would. A slow analytics query only shows a loading skeleton in the analytics slot, while the rest of the dashboard renders normally and stays interactive. This is the main reason teams reach for parallel routes on a dashboard: one slow section no longer blocks the whole page from becoming visible.
The same isolation applies to failures. If the analytics slot throws while fetching data, its own error boundary catches it and shows a retry message in that slot only, while the team slot and the rest of the layout stay fully usable. Without parallel routes, a single failing fetch anywhere on the page would normally trip the nearest shared error boundary and take down more of the screen than the one broken section actually warranted.
When to reach for parallel routes
| Use case | Fits parallel routes |
|---|---|
| Dashboard sections that load at different speeds | Yes |
| Tabs that should keep independent navigation history | Yes |
| A single page with one straightforward layout | No, adds unneeded complexity |
A single page with one linear layout rarely benefits from slots, since the extra props and default files add real overhead for no independent behavior to show for it. Reach for parallel routes once a page genuinely has more than one region that should load, error, and update on its own schedule, such as a social feed next to a notifications panel that both fetch from different, unrelated sources.
Parallel routes combine with intercepting routes to build shareable modal patterns, covered in intercepting routes in Next.js. For the layout rules that apply to any nested route, see layouts in Next.js.
Rune AI
Key Insights
- A slot folder is written with an @ prefix and is not a URL segment.
- Slots are passed to the parent layout as props alongside children.
- The children prop is itself an implicit slot for the regular page.
- A default.js file supplies fallback content for a slot on hard navigation.
- Each slot can stream and show loading or error states independently.
Frequently Asked Questions
Does a slot name appear in the URL?
What happens to a slot with no matching page after a hard refresh?
Can all slots be independently static or dynamic?
Conclusion
Parallel routes let a layout render more than one independently navigable page at once through named slots. Each slot streams, loads, and errors on its own, which fits dashboards and any view built from several unrelated sections.
More in this topic
`generateMetadata` Explained with Real Examples
What generateMetadata does, when it runs, and how to use it for real routes: awaited params, deduplicated data fetching, extending parent metadata, and returning a 404 from metadata.
Canonical URLs in Next.js: `metadataBase`, `alternates.canonical`, and Dynamic Pages
How canonical URLs work in the Next.js App Router: setting metadataBase once, writing alternates.canonical per route, handling dynamic segments, and what happens when the base URL is missing.
Open Graph and Twitter Card Metadata in Next.js
How to write Open Graph and Twitter card metadata in the Next.js App Router: the openGraph and twitter fields, automatic card defaults, article tags, and image merge rules.