Carsten Ruhr

NextJS 13

Another day, another Framework release. This time it's the release of NextJS 13.0.
So let's have a look at the most interesting new features:

Layouts

For this, we need to know that routing changed a bit in NextJS 13. Instead of "one-file-per-page" NextJS now follows a "one-directory-per-page" approach. In the app folder you can create pages by adding a (sub)directory with a page.tsx file which outputs the page content as JSX. Alongside this page.tsx you can create a layout.tsx which defines the common UI for multiple pages. A layout can contain other layouts or pages.
There are also some other special files you can use. More on them here: https://beta.nextjs.org/docs/routing/fundamentals#special-files.

Server Components

Pages - as described above - are now server components. This should reduce the amount of JS sent to the client. It also means you don't need to fiddle with getServerSideProps anymore.
Instead, you now need to explicitly declare client components with 'use client'; at the top of the file.
Here is a nice overview over what to use when: https://beta.nextjs.org/docs/rendering/server-and-client-components#when-to-use-server-vs-client-components

Streaming

NextJS now partially displays layouts and pages that do not require data fetching while other components are still waiting for their data. For the waiting components you can define a "loading state component" which gets displayed in the meantime.
Why is this special? Because the "waiting" components load their data on the server. So we get partial UI from the server which gets completed over time. More on this over at https://beta.nextjs.org/docs/data-fetching/streaming-and-suspense

Data fetching

Closely related to streaming is the new way to fetch data. And this is a nice one. You can just have an async function and "await it" in the page (or layout or component). Once the data becomes available and unblocks the rendering, NextJS (or rather React) does its thing and sends the rendered component to the client.
Here is an example:

const getSomeData = async () => {
  const res = await fetch('...')
  return await res.json()
}

export default async function Page() {
    const data1 = await getSomeData()
    // OR use the new react "use" hook
    const data2 = use(getSomeData())


    return `...`
}

Find more on fetching here: https://beta.nextjs.org/docs/data-fetching/fetching

Mutating

This is not done yet. There is a recommended way on how to mutate data, but the NextJS team is working on a better way.

Turbopack

Blazingly fast builds with the almighty power of Rust.

Two more noteworthy improvements

  • The image tag becomes faster and easier to use 🌠
  • The link tag doesn't require the nested a tag anymore 🎉

Unfortunately both of them are breaking changes and you would need to update either imports or some props to make your old tags work.

Conclusion

There is way more to this release than just the above-mentioned improvements. But those were the most impactful changes. To harness the true potential of NextJS 13 in an existing project, you have quite some re-writing to do. Luckily enough this can be done incrementally since the old way of routing is still supported.
If you adopt NextJS 13 without re-writing your app structure, you still benefit from Turbopack and several other improvements.