Next.js 13, a pivotal update in the React framework’s evolution, brings a game-changing feature: the App Router. It represents a significant departure from the previous version, with a comprehensive rewrite of the routing system, set to transform Next.js app development.
The debut of the app directory is a pivotal moment, offering numerous upgrades compared to the traditional pages directory. After a series of experimental releases, it has now become the default approach for creating Next.js applications. In this article, we’ll explore the exciting improvements that Next.js 13 has introduced, focusing on the innovative App Router and the evolution of the app directory as the new Next.js development standard.
Using conventional filenames, we can add various types of components in the app
directory. This is a big improvement over the current routing system, which requires us to use a specific directory structure to define pages, API handlers, and so on.
What does this mean? From now on, we can create various types of components in the app
directory using a specific filename convention specific to Next.js:
- Pages are defined as
page.tsx
- Layouts are defined as
layout.tsx
- Templates are defined as
template.tsx
- Errors are defined as
error.tsx
- Loading states are defined as
loading.tsx
- Not found pages are defined as
not-found.tsx
Let’s now dive into what these components offer to developers!
Pages
To create pages within the new app directory, we adhere to a specific convention: naming the file page.tsx
. This means that when defining a page in the app directory, the file should be named page.tsx
. For instance, if you wish to define the home page for your website, you can do so by placing the page in the app/(site)
directory and naming it page.tsx
.
function NewPage() {
return <div>New Page</div>;
}
export default NewPage;
To specify the metadata of a page, we can export the constant metadata
property in the page.tsx
file:
export const metadata = {
title: 'New Page',
description: 'This is a new page in Next.js 13',
};
Layouts
The new App Router in Next.js brings a powerful feature: Layouts. These Layouts wrap pages, offering not just consistent UI but also reusable data-fetching and logic.
By default Next.js now needs one root layout component:
export const metadata = {
title: 'Next.js Application',
description: 'A Next.js app using the new App Router',
};
async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang={'en'}>
<body>{children}</body>
</html>
);
}
export default RootLayout;
Layouts are created using the convention of naming a file layout.tsx
in the app directory. When you define a layout this way, Next.js will automatically apply that layout to all the pages within the same directory. For instance, if you have a layout defined in app/(site)/layout.tsx
, Next.js will use that layout for all pages in theapp/(site)
directory.
export default async function SiteLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div>
<main>
{children}
</main>
</div>
);
}
Loading States
When transitioning between pages, it’s often desirable to show a loading indicator. To achieve this, we can utilize a loading.tsx
file that can be defined in each directory.
In this loading.tsx
file, you have the flexibility to include any component of your choice to be displayed while the page is loading. This could be a top bar loader, a loading spinner, or even a combination of both.
export default function Loading() {
return <div>Loading...</div>;
}
Error Handling
At the moment, you can define a “not found” page using the convention not-found.tsx
:
export default function NotFound() {
return (
<>
<h2>404 Not Found</h2>
<p>The requested resource does not exist</p>
</>
);
}
Conclusion
In this article, we’ve explored the utilization of the new App Router featured in Next.js 13.
While the patterns and conventions covered here are considered experimental and subject to potential changes in the future, they already offer significant utility. You can confidently begin implementing them in your projects today.