Pages and Layouts

We recommend reading the Routing Fundamentals and Defining Routes pages before continuing.

Next.js 13 introduced new file conventions to allow you to easily create pages, shared layouts, and templates. This page will guide you through how to use these special files in your Next.js application.

Pages

A page is UI that is unique to a route. Pages can be defined by exporting a component from a page.js file. You can use nested folders to define routes and page.js files to make a route publicly accessible.

Create your first page by adding a page.js file inside the app directory:

Page File
app/page.js
// `app/page.js` is the UI for the root `/` URL
export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

Good to know:

  • A page is always the leaf of the route subtree.
  • js, jsx or tsx file extensions can be used for Pages.
  • A page.js file is required to make a route segment publicly accessible.
  • Pages are Server Components by default but can be set to a Client Component.
  • Pages can fetch data. View the Data Fetching section for more information.

Layouts

A layout is UI that is shared between multiple pages. On navigation, layouts preserve state, remain interactive, and do not re-render. Layouts can also be nested.

A layout can be defined by default exporting a React component from a layout.js file. The component should accept a children prop which will be populated with a page, another nested layout, loading UI, or error UI during rendering.

Layout File
app/dashboard/layout.tsx
export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode,
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>

      {children}
    </section>
  );
}

Good to know:

  • The top-most layout is called the Root Layout. This is a required layout that is shared across all pages in an application. It must contain the html and body tags.
  • Any route segment can optionally define its own Layout. These layouts will be shared across all pages in the segment.
  • Layouts in a route are nested by default. Each ancestor layout wraps the layout below it using children.
  • You can use Route Groups to opt specific route segments in and out of shared layouts.
  • Layouts are Server Components by default but can be set to a Client Component.
  • Layouts can fetch data. View the Data Fetching section for more information.
  • It's not possible to pass data between a parent layout and its children. However, you can fetch the same data in a route more than once, and React will automatically dedupe the requests without affecting performance.
  • js, jsx, or tsx file extensions can be used for Layouts.
  • A layout.js and page.js file can be defined in the same folder. The layout will wrap the page.

Root Layout (Required)

The root layout is defined at the top level of the app directory and applies to all routes. This layout enables you to modify the initial HTML returned from the server.

app/layout.tsx
export default function RootLayout({ children }: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

Good to know:

  • The app directory must include a root layout.
  • The root layout must define <html>, and <body> tags since Next.js does not automatically create them.
  • You can use the head.js special file to manage <head> HTML elements that change between route segments. For example, the <title> element.
  • You can use route groups to create multiple root layouts. See an example here.
  • The root layout is a Server Component by default and can not be set to a Client Component.

Migrating from the pages directory: The root layout replaces the _app.js and _document.js files. View the migration guide.

Nesting Layouts

Layouts defined inside a folder apply to specific route segments and render when those segments are active. By default, layouts in the file hierarchy are nested, which means they wrap child layouts via their children prop.

Nested Layout
app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode,
}) {
  return <section>{children}</section>;
}

If you were to combine the two layouts above, the root layout (app/layout.js) would wrap the dashboard layout (app/dashboard/layout.js), which would wrap route segments inside app/dashboard/*.

The two layouts would be nested as such:

Nested Layouts UI

Templates

Templates are similar to layouts in that they wrap each child layout or page. Unlike layouts that persist across routes and maintain state, templates create a new instance for each of their children on navigation. This means that when a user navigates between routes that share a template, a new instance of the component is mounted, DOM elements are recreated, state is not preserved, and effects are re-synchronized.

There may be cases where you need those specific behaviors, and templates would be a more suitable option than layouts. For example:

  • Enter/exit animations using CSS or animation libraries.
  • Features that rely on useEffect (e.g logging page views) and useState (e.g a per-page feedback form).
  • To change the default framework behavior. For example, Suspense Boundaries inside layouts only show the fallback the first time the Layout is loaded and not when switching pages. For templates, the fallback is shown on each navigation.

Recommendation: We recommend using Layouts unless you have a specific reason to use Template.

A template can be defined by exporting a default React component from a template.js file. The component should accept a children prop which will be nested segments.

Template File
app/template.tsx
export default function Template({ children }: {
  children: React.ReactNode
}) {
  return <div>{children}</div>;
}

The rendered output of a route segment with a layout and a template will be as such:

Output
<Layout>
  {/* Note that the template is given a unique key. */}
  <Template key={routeParam}>{children}</Template>
</Layout>

Modifying <head>

In the app directory, you can modify the <head> HTML elements such as title and meta using a new special head.js file. This replaces next/head in the pages directory.

Head File
app/post/[slug]/head.tsx
async function getPost(slug) {
  const res = await fetch('...');
  return res.json();
}

export default async function Head({ params }) {
  const post = await getPost(params.slug);

  return (
    <>
      <title>{post.title}</title>
    </>
  )
}

Good to know:

  • For now, only certain tags are allowed to be returned from the Head export:
    • <title>
    • <meta>
    • <link> (only if it has the attribute precedence)
    • <script> (only if it has the attribute async)
  • If you need to fetch data for head and also use the same data in a layout or page, you can fetch the data twice and Next.js will automatically dedupe the requests. See the Fetching data page for more information.

Warning: Currently, the <Head> export does not re-render on client-side transition using next/link, only on initial render and reloads. To work around this for <title>, you can use a client component with useEffect that updates document.title. We plan to fix this in a future release.

Next Steps