Migrating to NextJs 13
Tags: nextjs, typescript, javascript, react
Published: 2022-11-08 12:42:26

## Introduction
With all the buzz around NextJS 13 recently, I decided to take the opportunity to upgrade my personal website from 12 to 13.

The current setup is that I have a NextJS 12 app which serves a single page. It makes use of `getServerSideProps` to fetch data relating to my latest blog posts and my latest packages that I have published. It's pretty simple really and does the job for what I need right now.

## The Migration Process
As part of this upgrade I wanted to give a shot at moving to the new app directory structure.

Firstly you have to run some updates to your package versions:
```sh
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
# or
yarn upgrade next react react-dom eslint-config-next --latest
# or
pnpm up next react react-dom eslint-config-next --latest
```
_The above is taken from [Vercel's upgrade page](https://nextjs.org/docs/upgrading)._

Secondly you need to adjust your `next.config.js` to include the following code block to enable app structure routing:
```js
const nextConfig = {
  experimental: {
    appDir: true,
  },
};
```

Once this has been done you then need to start migrating the different parts affected by the major bump. [You can view them here at Vercel's hidden beta upgrade page](https://beta.nextjs.org/docs/upgrade-guide) which is frustratingly hard to find.

The most major parts to the upgrade that I found were:
* Components are now react-server-components by default unless you specify `use client` at the top of your file. This can cause breakages in existing code. Previous hooks such as `useRouter()` have been replaced and the new ones are only available in client components.
* The folder structure for routing. See a comparison below.

### NextJS 12
```
project
│   
└───/pages
   │   index.tsx
   │   projects.tsx
   └───/api
       │   hello-world.ts

```
### vs
### NextJS 13
```
project
│   
└───/app
    │   page.tsx (represents '/' route)
    └───/projects
        │   page.tsx (represents '/projects' route)
└───/pages
   └───/api (api routes are still in a pages folder)
       │   hello-world.ts

```
* Layouts have changed. You can share layouts between routes really easily or just have your normal layout at root. Layouts now just take a children prop typed as `React.ReactNode`. No typings of component and page props.
* You do not need a `<head>` section inside of your layout. This is done via a `head.tsx` file which contains all the declarations of your head tags etc.
* Caching requests with fetch inside of pages is so easy and code looks a lot cleaner than the old `getServerSideProps()`. 

```js
fetch(url, { next: { revalidate 60 } }); // 60 second cache
```
* If you run into unhelpful errors then you will most likely struggle to find answers to your issues via Google. But that's due to the nature of new technology!
* `<Image />` tag has been upgraded - but you can revert to the old version by changing your import to something like this `import Image from 'next/legacy/image';`. I had to due to some errors that I ran into during my upgrade.
* `<Link />` tag now renders an `<a>` tag by default. So you no longer need to wrap an a tag inside of a Link tag.
* No changes to api routes. They stay inside of the pages directory. Which I was surprised at, I hope this changes soon!

## Deploying to Netlify
This was... painful to say the least.

Documentation isn't well presented and easily accessible. If you wish to use the new NextJS app structure, it is currently part of an extended version of their plugin to enable it for deployments.

Ensure you upgrade `@netlify/plugin-nextjs` to this:
```json
"@netlify/plugin-nextjs": "^4.28.4-appdir.0",
```

Your existing .toml setup should be fine as it is.

I also found that running the build locally and then serving it and testing the build was absolutely fine. But when deployed to netlify I got a 500. Turns out the issue was because there was an import of `next/head` which isn't used anymore and doesn't play nicely when running inside of netlify.

To help others with this in the future, below is a link of references that I found helpful when migrating my app:
1. https://nextjs.org/docs/upgrading - Vercels snapshot update of upgrading.
2. https://beta.nextjs.org/docs/upgrade-guide - Vercels in-depth (kinda) guide upgrading.
3. https://www.netlify.com/blog/deploy-nextjs-13/ - Netlify's blog post around migrating to NextJS 13.

## Overall
I spent a great deal of time migrating due to little gotcha's  here and there. I'm happy it's done and I can test the new features it provides. But if my experience is anything to go by, I would allow a fair amount of time to do this with due care and attention. But maybe it was my late night coding brain that caused me to be so slow at upgrading.

Thanks for reading!👋