File-based routing is the backbone of every Next.js app; layouts avoid repeating navigation and shells.
In the App Router, folders define URL segments and special files define what renders:
page.tsxmakes a segment publicly accessible and exports the page component.app/page.tsxis/,app/blog/page.tsxis/blog,app/blog/archive/page.tsxis/blog/archive.layout.tsxwraps all pages below it. It receiveschildren(the page or nested layout) and is shared across navigations.
A folder without page.tsx is not a route, so you can colocate components, tests and styles inside app/ safely. Prefix a folder with an underscore (_components) to make the intent explicit.
Layouts nest: app/layout.tsx wraps app/dashboard/layout.tsx, which wraps app/dashboard/settings/page.tsx. On navigation between pages under the same layout, the layout is not re-rendered and keeps its state: an open sidebar or a search input stays as it was. Only the changed segment renders. (If you need a fresh instance per navigation, use template.tsx instead of layout.tsx.)
Pages and layouts are Server Components by default and can be async.
Other special files you will meet soon: loading.tsx, error.tsx, not-found.tsx and route.ts. Next.js composes them into a fixed hierarchy per segment: layout, then template, error boundary, loading boundary, not-found boundary, and finally the page.
Example
// app/dashboard/layout.tsx - shared by every page under /dashboard
import Link from 'next/link'
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex">
<nav>
<Link href="/dashboard">Overview</Link>
<Link href="/dashboard/settings">Settings</Link>
</nav>
<main>{children}</main> {/* the active page renders here */}
</div>
)
}
// app/dashboard/page.tsx -> /dashboard
export default function Overview() {
return <h1>Overview</h1>
}
// app/dashboard/settings/page.tsx -> /dashboard/settings
// export default function Settings() { return <h1>Settings</h1> }
// app/dashboard/_components/chart.tsx -> not a route (no page.tsx)Remember
- Folders = URL segments;
page.tsxmakes a segment routable layout.tsxwraps child segments and keeps its state across navigations- Files without
page.tsx(or in_folders) can be colocated safely
Watch out for
- Putting per-page data or state in a layout and expecting it to reset on navigation; layouts persist.