patterntypescriptnextjsTip
Parallel Routes: @folder convention for simultaneous layouts
Viewed 0 times
Next.js 13+ with App Router
parallel routesslots@folderdashboard layoutindependent loadingsimultaneous rendering
Error Messages
Problem
Rendering multiple independent sections of a page (like a dashboard with separate analytics and feed panels) that each have their own loading/error states requires duplicating logic or using complex state management.
Solution
Use parallel routes with the @slot convention in the same layout:
// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
analytics,
feed,
}: {
children: React.ReactNode;
analytics: React.ReactNode;
feed: React.ReactNode;
}) {
return (
<div className='dashboard'>
<main>{children}</main>
<aside>{analytics}</aside>
<section>{feed}</section>
</div>
);
}
// File structure:
// app/dashboard/@analytics/page.tsx — renders in analytics slot
// app/dashboard/@feed/page.tsx — renders in feed slot
// app/dashboard/@analytics/loading.tsx — independent loading UI
// app/dashboard/@feed/error.tsx — independent error boundary
// app/dashboard/@analytics/page.tsx
export default async function AnalyticsPanel() {
const data = await fetchAnalytics();
return <Chart data={data} />;
}
// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
analytics,
feed,
}: {
children: React.ReactNode;
analytics: React.ReactNode;
feed: React.ReactNode;
}) {
return (
<div className='dashboard'>
<main>{children}</main>
<aside>{analytics}</aside>
<section>{feed}</section>
</div>
);
}
// File structure:
// app/dashboard/@analytics/page.tsx — renders in analytics slot
// app/dashboard/@feed/page.tsx — renders in feed slot
// app/dashboard/@analytics/loading.tsx — independent loading UI
// app/dashboard/@feed/error.tsx — independent error boundary
// app/dashboard/@analytics/page.tsx
export default async function AnalyticsPanel() {
const data = await fetchAnalytics();
return <Chart data={data} />;
}
Why
Parallel routes allow multiple pages to be rendered simultaneously in the same layout. Each slot is independent — it can have its own loading.tsx, error.tsx, and data fetching. This enables true parallel data fetching at the route level without waterfalls.
Gotchas
- The @folder name (e.g., @analytics) maps to a prop in the parent layout, not a URL segment
- Each slot needs a default.tsx file for cases where the slot has no active state (e.g., on initial navigation)
- Parallel routes can be combined with intercepting routes for modal patterns
- Unmatched slots show default.tsx — if no default.tsx exists, the page renders a 404
Code Snippets
Layout with parallel route slots
// app/dashboard/layout.tsx — receives named slot props
export default function Layout({ children, analytics, team }) {
return (
<>
{children}
<Sidebar>{analytics}</Sidebar>
<Panel>{team}</Panel>
</>
);
}Context
When building dashboards or pages with multiple independent UI sections in Next.js App Router
Revisions (0)
No revisions yet.