This content originally appeared on DEV Community 👩💻👨💻 and was authored by ymc9
Next.js 13 has landed in a somewhat confusing way. Many remarkable things have been added; however, a good part is still Beta. Nevertheless, the Beta features give us important signals on how the future of Next.js will be shaped, so there are good reasons to keep a close eye on them, even if you're going to wait to adopt them.
This article is part of a series of experiences about the Beta features. Let's explore the new routing system today.
Next.js 13 introduced a brand new app
folder with a completely renovated routing system. It includes many improvements, and among all, the best gift is the new layout mechanism.
The app
folder can coexist with the old pages
folder as long as their routes don't clash, which allows you to adopt progressively. This post will cover the most notable new stuff with the app
folder.
New folder structure
The app
folder makes defining routes more explicit by requiring every route to be a folder. A route folder typically contains the following route files (with .js|.ts|.jsx|.tsx
suffix):
- page
Provides UI specific for this route.
- layout
Provides layout UI for this route and all descendant routes.
- loading
Provide a loading UI when server components for the route are being loaded - more on this in the next section.
- error
Provide UI for dealing with errors within and under this route (unless handled by another error
route in a descendant layer).
For more information about server components, check out the post below:
Fun With Next.js 13 Server Components
ymc9 for ZenStack ・ Nov 25 ・ 5 min read
Layout and nesting
The renovated folder structure sets a good foundation for introducing more convention-based route files. As a result, it's now much easier to create, share and nest layouts in Next.js than ever.
Let's see what got changed.
In previous versions
Before Next.js 13, the officially recommended approach for creating a nested layout is for each Page
to "declare" its layout, compose nesting, and then apply them at the top level in pages/_app
.
// pages/index.js
export default function Page() {
return (
/** Your content */
)
}
Page.getLayout = function getLayout(page) {
return (
<Layout>
<NestedLayout>{page}</NestedLayout>
</Layout>
)
}
// pages/_app.js
export default function MyApp({ Component, pageProps }) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout || ((page) => page)
return getLayout(<Component {...pageProps} />)
}
Although this approach results in optimal performance (because layouts are not remounted when changing route), it's cumbersome and unnatural, especially compared to what react-router offers.
With Next.js 13
The new routing system makes "layout" a first-class citizen. At any level of folders under app
(i.e., any level of routing), you can use a layout.tsx
to explicitly define a container component. This container component will automatically wrap around all pages in and under that folder. If there're multiple layout.tsx
components at different levels, a wrapping hierarchy is automatically constructed:
https://beta.nextjs.org/docs/routing/pages-and-layouts
Much more straightforward than the old getLayout
hack, isn't it?
A "grouping" feature is also available for you to create "logical" groups of pages to share the same layout without introducing an extra routing layer:
https://beta.nextjs.org/docs/routing/defining-routes#route-groups
As you can see, although /about
and /blog
don't share the same route prefix, they can share the same layout by residing in the same route group. Who doesn't like a bit more flexibility 👻?
Other notes
-
Passing data from layout to children
You can't do this. But it is not as serious a problem as it may seem because the new data fetching mechanism in Next.js 13 has built-in dedupe and caching, so it doesn't harm to fetch data in layout and its children components repeatedly.
I'll cover the new data-fetching system in a future post. -
Breaking out of layout hierarchy
There isn't a way for a page to "escape" the layout ancestors in the routing hierarchy. You'll have to design your routes or route groups carefully. In comparison, SvelteKit does provide better flexibility on this.
Error handling
Error handling is a small but convenient feature. The idea is quite simple:
- React has an Error Boundaries concept for capturing errors in a structured way.
- Next.js's route folders naturally form a component hierarchy.
- Why don't we invent a convention to handle errors at any level of routing?
That's what the error.tsx
file does. It's nothing but syntactic sugar for wrapping the descendent component tree within a <ErrorBoundary />
:
https://beta.nextjs.org/docs/routing/error-handling
With that, errors are localized to parts of UI rendered by sub-routes without affecting the display and interactivity of any other parts.
In the End
Thank you for your time reading to the end ❤️.
This is the second article of a series about the Beta features of Next.js 13. You can find the entire series here. If you like our posts, remember to follow us for updates at the first opportunity.
ZenStack is a toolkit for building secure CRUD apps with Next.js + Typescript. Our goal is to let you save time writing boilerplate code and focus on building what matters — the user experience.
This content originally appeared on DEV Community 👩💻👨💻 and was authored by ymc9
ymc9 | Sciencx (2022-12-01T16:00:09+00:00) Fun With Next.js 13 New Routing System. Retrieved from https://www.scien.cx/2022/12/01/fun-with-next-js-13-new-routing-system/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.