DEV Community

Cover image for Migrating to Next.js 13: A Simple Walkthrough
Leandro Nuñez for Digital Pollution

Posted on

Migrating to Next.js 13: A Simple Walkthrough

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

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.

// 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>
  )
}
Enter fullscreen mode Exit fullscreen mode

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.

// 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>)
}
Enter fullscreen mode Exit fullscreen mode

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.

// app/api/route.js

export async function GET(request) {
  // Your server-side logic here
}
Enter fullscreen mode Exit fullscreen mode

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.

// 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} />
}
Enter fullscreen mode Exit fullscreen mode

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

// app/page.js

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

  return data.posts
}
Enter fullscreen mode Exit fullscreen mode

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.

// tailwind.config.js

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

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

// app/layout.js

import '../styles/globals.css'

export default function RootLayout({ children }) {
  // ... your layout
}
Enter fullscreen mode Exit fullscreen mode

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


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!

Top comments (0)