Skip to Content
đźš§ This is WIP documentation for Nextra 4.0

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
src/app/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
src/app/documents/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 Layout

Why? 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:

src/app/documents/layout.tsx
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: 123

Think 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
src/app/auth/sign-in/page.tsx
const SignInPage = () => { return ( <div> Sign in page </div> ); } export default SignInPage;
src/app/auth/sign-up/page.tsx
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 page

But 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 page

Similarly, we can also create an Auth Layout for the auth folder:

src/app/(auth)/layout.tsx
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
Last updated on