Avatar

Salut, I'm Julia.

Upgrading From NextJS v12 to v13

#nextjs #react #typescript

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 react and react-dom to v18, along with the eslint-config-next package and relevant @types packages.
  • 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-library packages and deleted the @testing-library/react-hooks package, since this is now part of the main @testing-libray/react package.
    • Needed to fix some failing tests as a result of this:
      • waitForNextUpdate no longer exists when using renderHook. waitfor should be used instead.
      • React v18 seems stricter around proper use of act and waitFor when you're having to wait for React render cycles to complete.
  • 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-modules package as it's now in-built into v13 and no longer needed.
    • Amended next.config.js to account for this (we were using it to load in specific packages).
  • Amending any width and height props that were being passed to the Image component as strings (instead of numbers).
  • NextJS v12's Image component is now imported from next/legacy/image component. Importing from next/image means using the new v13 Image component.
    • A big difference is that NextJS has simplified how the final img element 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.
  • NextJS v13's Link component 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 passHref property.
    • A new eslint rule has been added to warn us in instances when the passHref should be used but is missing.
  • I went through all pages where we were using the Link and Image components 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/font component that helps minimise layout shift for self-hosted fonts.
  • New routing methodology with the introduction of the app directory, that's built on top of React Server Components.
  • 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 app directory 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.

Β© 2016-2024 Julia Tan Β· Powered by Next JS.