Parallel Routes
Parallel routes let you render multiple pages in the same layout simultaneously. Think: a dashboard with independently loading panels, or a modal that overlays the page.
1// Folder structure for parallel routes:2src/app/3└── dashboard/4 ├── layout.tsx5 ├── page.tsx6 ├── @analytics/7 │ └── page.tsx ← Renders in "analytics" slot8 ├── @notifications/9 │ └── page.tsx ← Renders in "notifications" slot10 └── @team/11 └── page.tsx ← Renders in "team" slot1// src/app/dashboard/layout.tsx2export default function DashboardLayout({3children,4analytics,5notifications,6team,7}: {8children: React.ReactNode;9analytics: React.ReactNode;10notifications: React.ReactNode;11team: React.ReactNode;12}) {13return (14 <div className="grid grid-cols-3 gap-4">15 <div className="col-span-2">{children}</div>16 <aside>17 {analytics}18 {notifications}19 {team}20 </aside>21 </div>22);23}Why parallel routes?
Intercepting Routes
Intercepting routes let you show a route as a modal on the current page, while keeping the full page accessible via direct URL. Instagram-style photo modals:
1src/app/2├── feed/3│ ├── page.tsx ← Feed page4│ └── (..)photo/[id]/5│ └── page.tsx ← Shows photo as MODAL on feed6└── photo/[id]/7 └── page.tsx ← Full photo page (direct URL)Convention: (.) intercepts same level, (..) one level up, (..)(..) two levels up, (...) from root.
Partial Prerendering (Experimental)
PPR combines static and dynamic rendering in a single route. The static shell is served instantly from CDN, then dynamic parts stream in. It's the future of Next.js rendering.
1// next.config.ts2import type { NextConfig } from "next";34const nextConfig: NextConfig = {5experimental: {6 ppr: true, // Enable Partial Prerendering7},8};910export default nextConfig;1import { Suspense } from "react";23// Static shell (pre-rendered at build time)4export default function ProductPage() {5return (6 <div>7 <h1>Product Details</h1> {/* Static */}8 <ProductInfo /> {/* Static */}9 10 <Suspense fallback={<p>Loading price...</p>}>11 <DynamicPrice /> {/* Dynamic, streams in */}12 </Suspense>13 14 <Suspense fallback={<p>Loading reviews...</p>}>15 <Reviews /> {/* Dynamic, streams in */}16 </Suspense>17 </div>18);19}This is where Next.js is heading