Migrating to Next.js 13: A Simple Walkthrough
Tags: nextjs, react, webdev, javascript
Published: 2023-10-17 09:17:39

**Hello there!**
I'm Leandro, coming to you from the heart of Argentina where I immerse myself in code, often more tangled than a good tango.
I love building with Next.js, and if you're anything like me, you're not just in this for the coding. 
It's about the connections we make and the stories we tell through our craft, right? 
Today, I’m here to chat about our next adventure: migrating from Next.js 12 to 13. No jargon, no fluff — just you, me, and some real talk about the nitty-gritty of upgrading. 
Ready to jump in? 
¡Vamos!

## Table of Contents
- [Introduction](#introduction)
- [Transitioning to the 'app' Directory Structure](#transitioning-to-the-app-directory-structure)
- [Fetching Data and Handling API Routes](#fetching-data-and-handling-api-routes)
- [Dynamic Paths and Incremental Static Regeneration](#dynamic-paths-and-incremental-static-regeneration)
- [Styling Changes](#styling-changes)
- [Conclusion](#conclusion)
- [References](#references)

## Introduction

In the realm of React development, Next.js has always been a game-changer, especially for folks like us who appreciate a framework that's both powerful and manageable. 
With the release of Next.js 13, things have gotten even more exciting. However, change can be challenging, and migration, a tad bit daunting. 
Fret not; we'll demystify this process step-by-step.

## Transitioning to the 'app' Directory Structure

First off, Next.js 13 introduces a shift in the directory structure. Instead of the pages directory acting as the sole hub, we now work with the `app` directory. 
This new setup offers more flexibility, especially when our projects begin to expand in complexity.

```javascript
// Before: pages/_app.js
// After: app/layout.js

import '../styles/globals.css'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
```

The `app` directory becomes the central place for our layouts, pages, and components, enhancing overall organization and scalability.

## Fetching Data and Handling API Routes

Next.js 13 simplifies data fetching. 
Remember `getServerSideProps` or `getStaticProps`? Well, they've become more intuitive. 
Instead of juggling different data fetching methods, you can now use straightforward functions in your `app` directory components.

```javascript
// app/page.js

async function getProjects() {
  const res = await fetch(`https://...`)
  const projects = await res.json()

  return projects
}

export default async function Index() {
  const projects = await getProjects()

  return projects.map((project) => <div>{project.name}</div>)
}
```

API routes see a transformation as well, replaced by Route Handlers in the `app` directory. These handlers allow for more customizability and direct interactions with requests and responses.

```javascript
// app/api/route.js

export async function GET(request) {
  // Your server-side logic here
}
```

## Dynamic Paths and Incremental Static Regeneration

Dynamic routing and paths also get a revamp, making them more intuitive to work with, especially within nested routes. 
The function `generateStaticParams` replaces `getStaticPaths`, simplifying how we define our dynamic routes.

```javascript
// app/posts/[id]/page.js

export async function generateStaticParams() {
  return [{ id: '1' }, { id: '2' }]
}

async function getPost(params) {
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  return post
}

export default async function Post({ params }) {
  const post = await getPost(params);

  return <PostLayout post={post} />
}
```

Moreover, the new `revalidate` option with data fetching methods adds the Incremental Static Regeneration feature, allowing pages to update automatically after a specified period.

```javascript
// app/page.js

async function getPosts() {
  const res = await fetch(`https://.../posts`, { next: { revalidate: 60 } })
  const data = await res.json()

  return data.posts
}
```

## Styling Changes

Styling your components is more flexible in Next.js 13. Global styles are no longer restricted to a specific file, meaning you can maintain styles within relevant component files, enhancing modularity.

If you're using Tailwind CSS, don't forget to update your `tailwind.config.js` to include the new `app` directory.

```javascript
// tailwind.config.js

module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}', // New line to add
    // ... other paths
  ],
}
```

And, of course, continue importing your global styles as needed.

```javascript
// app/layout.js

import '../styles/globals.css'

export default function RootLayout({ children }) {
  // ... your layout
}
```

## Conclusion

So, there we have it, amigos! Transitioning to Next.js 13 might seem like a handful at first, but it's a smooth sail once you get the hang of the changes. The enhancements in data fetching, API handling, routing, and styling are all aimed at making our lives as developers easier, allowing us to focus more on creating fantastic web experiences. As we adapt, let's continue to share our knowledge and grow together in this ever-evolving tech landscape.

## References

- Official Next.js documentation: [App Router Migration](https://nextjs.org/docs/pages/building-your-application/upgrading/app-router-migration)


---

I hope this guide serves as a helpful resource for all of you embarking on this migration journey. 
Remember, staying updated with the latest changes helps us grow and innovate in our projects. 
**¡Hasta la próxima!**