Layout
Root Layout
There is a layout.tsx file in the app directory, which specifies the fonts, style files, metadata, and basic layout structure to be used in the entire project.
- page.tsx
- layout.tsx
import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";
const geistSans = localFont({
src: "./fonts/GeistVF.woff",
variable: "--font-geist-sans",
weight: "100 900",
});
const geistMono = localFont({
src: "./fonts/GeistMonoVF.woff",
variable: "--font-geist-mono",
weight: "100 900",
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}Documents Layout
Now let’s create a layout.tsx under the documents folder:
- page.tsx
- layout.tsx
- layout.tsx
const DocumentsLayout = () => {
return (
<div>Documents Layout</div>
);
}
export default DocumentsLayout;Then visit http://localhost:3000/documents  or http://localhost:3000/documents/123 , you’ll see the same page content:
Documents LayoutWhy? Because the layout.tsx should have a children props to render the directories and pages content at the same level with it. If there is no children props, the content of layout.tsx will cover all pages under the same parent directory with it.
So let add children props for the DocumentsLayout:
interface DocumentsLayoutProps {
children: React.ReactNode;
}
const DocumentsLayout = ({children}: DocumentsLayoutProps) => {
return (
<div>
<div className="w-full bg-blue-100">
Documents Layout
</div>
{children}
</div>
);
}
export default DocumentsLayout;Now visit http://localhost:3000/documents  or http://localhost:3000/documents/123  again. You can see the Documents Layout as well as the page’s original content:
Page result
// http://localhost:3000/documents
Documents Layout
Documents Page
// http://localhost:3000/documents/123
Documents Layout
Document ID: 123Think of the Documents Layout as a navigation bar, and you’ll understand how those websites you see are able to implement the same navigation bar on different pages.
Auth Routing and Layout
Now assume that we have to build an auth system for the project. It should have a sign-in page and a sign-up page at least. In order to make the project structure clear, we’ll put the two pages into a parent folder named auth:
- layout.tsx
- layout.tsx
const SignInPage = () => {
return (
<div>
Sign in page
</div>
);
}
export default SignInPage;const SignUpPage = () => {
return (
<div>
Sign up page
</div>
);
}
export default SignUpPage;After creating the two pages, you could visit http://localhost:3000/auth/sign-in  and http://localhost:3000/auth/sign-up  to see the content.
Page result
// http://localhost:3000/sign-in
Sign in page
// http://localhost:3000/sign-up
Sign up pageBut we actually don’t need the auth to be in the url, this folder is just for grouping. To make the url shorter, We could add a () into the auth filename:
- layout.tsx
- layout.tsx
Now you can visit http://localhost:3000/sign-in  and http://localhost:3000/sign-up  directly to get the pages.
Page result
// http://localhost:3000/sign-in
Sign in page
// http://localhost:3000/sign-up
Sign up pageSimilarly, we can also create an Auth Layout for the auth folder:
interface AuthLayoutProps {
children: React.ReactNode;
}
const AuthLayout = ({children}: AuthLayoutProps) => {
return (
<div>
<div className="w-full bg-blue-100">
Auth Navbar
</div>
{children}
</div>
);
}
export default AuthLayout;Now visit http://localhost:3000/sign-in  and http://localhost:3000/sign-up  to see it’s content.
Page result
// http://localhost:3000/sign-in
Auth Navbar
Sign in page
// http://localhost:3000/sign-up
Auth Navbar
Sign up page