Quick Overview of Next.js 13 Routing System
Tags: nextjs, react, fullstack, webdev
Published: 2022-12-01 16:00:09

---
description: An introduction to the beta routing system of Next.js 13 — what's changed and why it's much better.
---

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**

  Provides a loading UI when server components for the route are being loaded - more on this in the next section.

- **error**

  Provides 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:

{% embed https://dev.to/zenstack/fun-with-nextjs-13-server-components-o37 %}

## 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`.

```tsx
// pages/index.js

export default function Page() {
  return (
    /** Your content */
  )
}

Page.getLayout = function getLayout(page) {
  return (
    <Layout>
      <NestedLayout>{page}</NestedLayout>
    </Layout>
  )
}
```

```tsx
// 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:

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ltw0heq8btqkgxi2me9s.png" />
  <figcaption>https://beta.nextjs.org/docs/routing/pages-and-layouts</figcaption>
</figure>
<p>&nbsp;</p>

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:

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r3ik2zwaqe7bm5i4w973.png" />
  <figcaption>https://beta.nextjs.org/docs/routing/defining-routes#route-groups</figcaption>
</figure>
<p>&nbsp;</p>

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

1. 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.

2. 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](https://kit.svelte.dev/docs/advanced-routing#advanced-layouts-breaking-out-of-layouts) on this.

## Error handling

Error handling is a small but convenient feature. The idea is quite simple:

1. React has an [Error Boundaries](https://reactjs.org/docs/error-boundaries.html) concept for capturing errors in a structured way.
2. Next.js's route folders naturally form a component hierarchy.
3. 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 />`:

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48gr2rlv7i8kk8u2hmzb.png" />
  <figcaption>https://beta.nextjs.org/docs/routing/error-handling</figcaption>
</figure>
<p>&nbsp;</p>

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](https://dev.to/ymc9/series/20755). If you like our posts, remember to follow us for updates at the first opportunity.

---

P.S. We're building [ZenStack](https://zenstack.dev?utm_campaign=devto&utm_medium=organic&utm_content=nextjs_routing_system) — a toolkit for developing 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.