Parallel Routes
@ prefix — a slot— and each slot behaves like its own mini page tree, with its own loading and error states, that the parent layout can place anywhere it wants.Folder structure
app/
dashboard/
@analytics/
page.tsx
@team/
page.tsx
layout.tsx
page.tsx@), alongside the regular children prop for the unnamed default slot.app/dashboard/layout.tsx
export default function DashboardLayout({
children,
analytics,
team,
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<div className="dashboard-grid">
<section className="main">{children}</section>
<section className="analytics">{analytics}</section>
<section className="team">{team}</section>
</div>
)
}Classic use case: an independent-panel dashboard
loading.tsx to stream in as soon as it's ready, without waiting for its sibling slots.default.tsx: filling the gap when a slot doesn't match
Slots don't all need a matching sub-route for every URL under the layout. When the current URL doesn't match anything inside a given slot, Next.js needs something to render for that slot instead — and by default, that's a 404 for the whole layout, which is rarely what you want.
app/dashboard/@team/default.tsx
export default function Default() {
// Rendered whenever the current URL doesn't match a page
// inside the @team slot — keeps the rest of the layout intact.
return null
}default.tsx to every slot that won't have a matching route for every possible URL under that layout. It's the fallback that prevents an unrelated navigation elsewhere in the layout from producing an unexpected 404 for a slot that was never meant to handle that URL.A folder prefixed with
@defines a named slot, passed to the parent layout as a prop with that same name.Each slot is its own independent page tree — with its own
loading.tsxanderror.tsxif needed.The unnamed
childrenprop is the default slot every layout already has.Add
default.tsxto a slot to avoid a 404 when the current URL has no matching route inside that slot.