Loading content…
Loading content…
Master advanced routing mechanics: Parallel routes, Intercepting routes, and Middleware with Edge Runtime details
@folder)@slotName) and is passed directly to the parent layout as a prop.app/
dashboard/
layout.tsx → Consumes @analytics and @team props
page.tsx → The core dashboard page view
@analytics/
page.tsx → Rendered in the analytics slot
loading.tsx → Analytics skeleton loader
@team/
page.tsx → Rendered in the team slot
// app/dashboard/layout.tsx
import React from "react";
interface LayoutProps {
children: React.ReactNode;
analytics: React.ReactNode; // Slot prop
team: React.ReactNode; // Slot prop
}
export default function DashboardLayout({ children, analytics, team }: LayoutProps) {
return (
<div className="flex flex-col gap-6">
<header className="p-4 bg-slate-900 text-white rounded-xl">Dashboard Header</header>
<main className="grid grid-cols-1 md:grid-cols-3 gap-6">
<section className="md:col-span-1">{children}</section>
<section className="md:col-span-1 border rounded-xl p-4 bg-white">{analytics}</section>
<section className="md:col-span-1 border rounded-xl p-4 bg-white">{team}</section>
</main>
</div>
);
}
default.tsxdefault.tsx fallback file inside your slot directories, Next.js will render a 404 error page.Common Pitfall
default.tsx file in every parallel slot directory. It can simply return null or render a fallback component, ensuring reloads do not trigger random 404 errors.(.)folder, (..)folder)(.) matches segments on the same level(..) matches segments one level above(..)(..) matches segments two levels above(...) matches segments from the root app directory/photo/:id route and render it as an overlay modal without changing the page context. If they copy the URL, send it to a friend, or refresh the browser, the page renders in full layout view.app/
page.tsx → Main Feed (Lists photo cards)
photo/
[id]/
page.tsx → Full Photo Detail Page (Served on direct URL load)
@modal/
default.tsx → Returns null (initial load fallback)
(.)photo/
[id]/
page.tsx → The modal overlay component (Loads on feed click)
fs, path, or child_process), and limited NPM package support.// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("session")?.value;
const { pathname } = request.nextUrl;
// Protect dashboard routes
if (pathname.startsWith("/dashboard") && !token) {
// Redirect unauthenticated user to login
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
// Config to select only matching paths (speeds up application assets loads)
export const config = {
matcher: ["/dashboard/:path*", "/admin/:path*"]
};
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// 1. Content Security Policy (CSP)
response.headers.set(
"Content-Security-Policy",
"default-src 'self'; script-src 'self' 'unsafe-inline' https://apis.google.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;"
);
// 2. Strict Transport Security (HSTS)
response.headers.set(
"Strict-Transport-Security",
"max-age=63072000; includeSubDomains; preload"
);
// 3. X-Frame-Options (Clickjacking protection)
response.headers.set("X-Frame-Options", "DENY");
// 4. Referrer Policy
response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
return response;
}
Senior Developer Wisdom
Routing & Middleware Checklist
Marking it complete updates your roadmap progress percentage.