Pages and Layouts
Vite Router Next has two file conventions, layout.[jt]sx
and page.[jt]sx
(abbreviated as .tsx
). These two files determine the layout structure of the application. layout.tsx
is used as the layout component, and page.tsx
acts as the page component, which is the leaf node of the entire route (a route has only one leaf node and must end with a leaf node).
Pages
A page is UI that is unique to a route. You can define pages by exporting a component from a page.[jt]sx
file. Use nested folders to define a route and a page.[jt]sx
file to make the route publicly accessible.
Create your first page by adding a page.[jt]sx
file inside the app directory:
export default function IndexPage() {
return <h1>Hello, Vite Router Next!</h1>
}
export default function AdminIndexPage() {
return <h1>Hello, Admin Index Page!</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 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.
The <Layout>
component refers to all layout.tsx
files under the pages/
directory. They represent the layout of the corresponding route segment and use <Outlet>
(React Router component) to represent child components.
import { Outlet } from 'react-router-dom';
export default function RootLayout() {
return <div>
<Suspense fallback={<div>Loading...</div>}>
<Outlet />
</Suspense>
</div>
}
INFO
<Outlet>
is a new API in React Router 6. For more details, please refer to Outlet.
WARNING
RootLayout
(/pages/layout.tsx
) must be use <Suspense>
component to wrap <Outlet>
component, otherwise it will not work. Because by default, all routes are lazy loaded, and <Suspense>
is used to handle lazy loading.
Nested Layouts
To simplify the introduction of the relationship between <Layout>
and <Outlet>
, the following file directory is used as an example:
.
└── pages
├── blog
│ └── page.tsx
├── layout.tsx
├── page.tsx
└── user
├── layout.tsx
└── page.tsx
- When the route is
/
, the<Outlet>
inpages/layout.tsx
represents the component exported inpages/page.tsx
, generating the following UI structure:
<Layout>
<Page />
</Layout>
- When the route is
/blog
, the<Outlet>
inpages/layout.tsx
represents the component exported inpages/blog/page.tsx
, generating the following UI structure:
<Layout>
<BlogPage />
</Layout>
- When the route is
/user
, the<Outlet>
inpages/layout.tsx
represents the component exported inpages/user/layout.tsx
. The<Outlet>
inpages/user/layout.tsx
represents the component exported inpages/user/page.tsx
, generating the following UI structure:
<Layout>
<UserLayout>
<UserPage />
</UserLayout>
</Layout>
In summary, if there is a layout.tsx
file under the sub-route's file directory, the <Outlet>
in the parent layout.tsx
will represent the layout.tsx
in the sub-route file directory. Otherwise, it will represent the page.tsx
in the sub-route file directory.