We recommend reading the Routing Fundamentals and Defining Routes pages before continuing.
The App Router inside Next.js 13 introduced new file conventions 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.
A page is UI that is unique to a route. You can define pages by exporting a component from a page.js
file. Use nested folders to define a route and a page.js
file to make the route publicly accessible.
Create your first page by adding a page.js
file inside the app
directory:
// `app/page.js` is the UI for the root `/` URL
export default function Page() {
return <h1>Hello, Next.js!</h1>;
}
Good to know:
.js
, .jsx
, or .tsx
file extensions can be used for Pages.page.js
file is required to make a route segment publicly accessible.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.
You can define a layout by default
exporting a React component from a layout.js
file. The component should accept a children
prop that will be populated with a child layout (if it exists) or a child page during rendering.
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:
html
and body
tags.children
prop..js
, .jsx
, or .tsx
file extensions can be used for Layouts.layout.js
and page.js
file can be defined in the same folder. The layout will wrap the page.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.
export default function RootLayout({ children }: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Good to know:
app
directory must include a root layout.<html>
and <body>
tags since Next.js does not automatically create them.<head>
HTML elements, for example, the <title>
element.Migrating from the
pages
directory: The root layout replaces the_app.js
and_document.js
files. View the migration guide.
Layouts defined inside a folder (e.g. app/dashboard/layout.js
) apply to specific route segments (e.g. acme.com/dashboard
) 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.
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:
You can use Route Groups to opt specific route segments in and out of shared layouts.
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:
useEffect
(e.g logging page views) and useState
(e.g a per-page feedback form).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.
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:
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>
<head>
In the app
directory, you can modify the <head>
HTML elements such as title
and meta
using the built-in SEO support:
export const metadata = {
title: 'Next.js'
};
export default function Page() {
return '...'
}
Alternatively, you can use generateMetadata
to fetch
metadata that requires dynamic values.
export async function generateMetadata({ params, searchParams }) {
return { title: 'Next.js' };
}
export default function Page() {
return '...'
}
Learn more about available metadata options in the API reference.