Loading lessons...
Pages and Root Layouts (page.tsx & layout.tsx)
Pages and Root Layouts (page.tsx & layout.tsx)
In the Next.js App Router, routing is strictly file-system based. Folders define route segments, while specific reserved file names create the user interface.
Reserved File Conventions
The two most fundamental files in any App Router route are:
page.tsx: Defines the unique UI rendered for a specific URL route segment.layout.tsx: Defines UI shared across multiple child pages and segments.
Root Layout Requirements
Every Next.js application must contain a Root Layout at app/layout.tsx. The Root Layout is top-level and must return the <html> and <body> tags.
// app/layout.tsx
import './globals.css';
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
export const metadata = {
title: 'Next.js App',
description: 'Built with App Router',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<nav className="border-b p-4">Global Header Nav</nav>
{children}
</body>
</html>
);
}
Defining Pages (page.tsx)
A page receives parameters automatically via props: params for dynamic route segments and searchParams for URL query parameters.
// app/dashboard/page.tsx
export default function DashboardPage({
searchParams,
}: {
searchParams: { tab?: string };
}) {
const currentTab = searchParams.tab || 'overview';
return (
<div className="p-6">
<h1 className="text-2xl font-bold">Dashboard</h1>
<p>Active Tab: {currentTab}</p>
</div>
);
}
Key Comparison: Pages vs Layouts
| Feature | page.tsx | layout.tsx |
|---|---|---|
| Primary Goal | Render unique route UI | Render shared UI container |
| Re-renders on Navigate | Yes (unmounts and remounts) | No (persists state across children) |
| Must Return HTML/Body? | No | Yes (Root Layout only) |
| Receives Children Prop? | No | Yes (children: React.ReactNode) |
| Receives searchParams? | Yes | No (Layouts do not receive searchParams) |
TL;DR
page.tsxrenders the specific view for a URL path.layout.tsxwraps child pages, preserving component state on navigation.- Root layout (
app/layout.tsx) is mandatory and must contain<html>and<body>. - Layouts do not receive
searchParamsto prevent unnecessary layout re-renders.