Thomathings

Updating Next.js to v13

Mar 29, 2023

Introduction

This blog has been using Next.js v12 for a while. Since its v13 with the page directory has been stable, I decided to update.
Not only I updated Next.js to v13, but I also fixed errors from other libraries. This is why I want to take a note.

Target audience

A user:

  • Wants to update Next.js from v12 to v13
  • Uses mdx-bundler to compile MDX files

Pull Request

This PR commits this update.

Updated Libraries

next
- 12.0.10
+ 13.2.4

react
- 17.0.2
+ 18.2.0

react-dom
- 17.0.2
+ 18.2.0

mdx-bundler
- 8.0.1
+ 9.2.1

next-pwa
- 5.4.4
+ 5.6.0

eslint-config-next
- 12.0.10
+ 13.2.4

What I did

Since Next.js v13 changes the APIs of the Link component, the Link no longer needs an anchor element as a child.

Warning: passHref is missing. See: https://nextjs.org/docs/messages/link-passhref @next/next/link-passhref

If you use v12 of eslint-config-next, ESLint shows you the above warning unless you update it to v13

Updating mdx-bundler to latest

Error: Package subpath './jsx-runtime.js' is not defined by "exports" in /path/to/repo/node_modules/react/package.json

When I updated next to v13 and executed next dev, dynamic page showed the above error. I guessed this error is from esbuild because I often saw esbuild creates the jsx-runtime.js file as the build output. In this blog, mdx-bundler is only the package using esbuild. So I just updated it to latest, then it fixed the error.

I think mdx-bundler fixed this at v8.1.0 which supports react v18.

Other Topics

Why not appDir?

Although I love using the appDir approach, the reason I didn't use in this blog is that I couldn't find a way this blog shows MDX which uses react hooks. I think I could do it with a combo of useEffect and useState, but it seems its implementation makes UX worse.

I also tried an approach that I pass the MDX content, which is serialized from a library such as next-mdx-remote, from the server component to the client component. Because of the serialization issue, I couldn't do that.

If I find a good solution for the MDX content, I'll make this blog move to appDir!

Why not Astro?

I've heard Astro is pretty good for a static site. It often is compared to Next.js because they have similar features.
The reason I stick with Next.js is the user experience of the page navigation.
In Astro, When a page moves to another page, users need to wait for the moment. But in Next.js using prerendering, it doesn't happen.
So I didn't move to Astro this time.