Upgrading From NextJS v12 to v13
4 min read
If y'll didn't already know, I use NextJS to run this website. I had been using NextJS v12 up until yesterday when I pushed some changes to upgrade to v13. π Prior to this, I spent a couple of weeks playing around with the upgrade, to understand what changes were needed to get an app upgraded and running in production.
The reason I did this was: (i) because it's fun to tinker, but more importantly (ii) I wanted to propose upgrading my team's NextJS app and needed to get a solid, working understanding before being able to convince my teammates to go along with the idea. That's one of the benefits of having a personal project - it allows you to mess around with new technology before deciding whether it's something worth pursuing when the risks are higher. π
I've now done the upgrade for both apps, and am happy to report that there were not a lot of issues to untangle. Much has been written about the NextJS v13 upgrade process and features, so I won't go into those in-depth here. I wrote an internal blog post for my team mates though, as a sort of TL;DR for the official docs, so I'll just reproduce the main points here.
Main changes needed to get the app working
General package amendments and upgrading to React v18
- Upgrading
reactandreact-domto v18, along with theeslint-config-nextpackage and relevant@typespackages. - Upgrading
babel-plugin-styled-components. - React v18 is stricter about improper nested HTML elements, so needed to fix a few instances of nested
<p>tags within other<p>tags that were coming in from our CMS. - Upgraded all the
@testing-librarypackages and deleted the@testing-library/react-hookspackage, since this is now part of the main@testing-libray/reactpackage.- Needed to fix some failing tests as a result of this:
waitForNextUpdateno longer exists when usingrenderHook.waitforshould be used instead.- React v18 seems stricter around proper use of
actandwaitForwhen you're having to wait for React render cycles to complete.
- Needed to fix some failing tests as a result of this:
- Fixing Typescript compilation errors in a number of our components (like our payment provider mock and router mock) due to missing functions.
NextJS v13 specific changes
- Removing
next-transpile-modulespackage as it's now in-built into v13 and no longer needed.- Amended
next.config.jsto account for this (we were using it to load in specific packages).
- Amended
- Amending any width and height props that were being passed to the
Imagecomponent as strings (instead of numbers). - NextJS v12's
Imagecomponent is now imported fromnext/legacy/imagecomponent. Importing fromnext/imagemeans using the new v13Imagecomponent.- A big difference is that NextJS has simplified how the final
imgelement is rendered with the removal of all the extraneous<span>tags, wrapping<img>. This means it's a lot easier to directly style the<img>element. - There's also better image optimisation and faster lazy loading out of the box.
- A big difference is that NextJS has simplified how the final
- NextJS v13's
Linkcomponent no longer accepts an<a>tag as a child - it should be text instead. ππ»- If the underlying component is not text, e.g. a Styled Component or a button, we should add the
passHrefproperty. - A new eslint rule has been added to warn us in instances when the
passHrefshould be used but is missing.
- If the underlying component is not text, e.g. a Styled Component or a button, we should add the
- I went through all pages where we were using the
LinkandImagecomponents to check that all was rendering properly with the v13 versions, and made appropriate changes where needed.
Other benefits of upgrading to NextJS v13
- Uses React 18 (read more about the changes here).
- The biggest addition is opt-in concurrent React and Suspense.
- Auto-batching of multiple state changes into a single re-render is also a nice add-on.
- New
next/fontcomponent that helps minimise layout shift for self-hosted fonts. - New routing methodology with the introduction of the
appdirectory, that's built on top of React Server Components.- Features support for layouts, nested routing, loading states and error handling. Read more about it here.
- Option to use faster Turbopack over Webpack (but realistically, weβre not really concerned with this at the moment). This is only available for testing in the dev environment.
Next steps
- Implement
next/font. It seems like a simple change. More can be read about why we might want to use it here. - Wait for the
appdirectory feature to be released out of beta before taking the decision on whether to move across to the new structure. Vercel does not currently recommend that this feature is used in production just yet.