avatarDenis Bunchenko

Summary

The provided content outlines a comprehensive guide for migrating from the Pages Router to the App Router in Next.js, detailing the necessary steps and considerations for a successful transition.

Abstract

The article discusses the transition from the Pages Router to the App Router in Next.js, emphasizing the benefits of adopting the newer, stable App Router introduced in Next.js 13 and enhanced in version 14. It provides a structured approach to migration, beginning with the creation of an app directory and a root layout, updating the useRouter hook, and revising data fetching methods. The guide is split into two parts, with the first part focusing on the app router structure, updates to the useRouter hook, metadata updates, and data fetching. It also addresses the need to handle React context providers differently due to the server-centric nature of the app directory's components. The article concludes by encouraging developers to embrace the App Router for its performance and maintainability improvements, with a promise to delve into additional topics such as error handling and styling in the second part of the guide.

Opinions

  • The author strongly recommends migrating to the App Router to leverage new features and performance optimizations.
  • The App Router is considered more efficient and is unlikely to receive significant updates, making it a future-proof choice for Next.js applications.
  • The migration process is presented as incremental and manageable, with the ability to work alongside the existing Pages Router to avoid disruptive changes.
  • The author suggests that maintaining the old pages directory during the migration phase is crucial to prevent breaking existing routes.
  • The use of Server Components by default in the app directory is highlighted as a key performance enhancement, with the option to use Client Components where necessary.
  • The article promotes the new Metadata API as a superior alternative to the old <Head /> component for managing metadata in Next.js applications.
  • The author advocates for server-side data fetching with Server Components to reduce client-server communication and improve security by preventing sensitive information exposure.
  • The guide emphasizes the importance of understanding and utilizing the new caching and revalidating features provided by Next.js for server-side data fetching.
  • The author concludes with a positive outlook on the App Router migration, suggesting that it will lead to more performant and maintainable Next.js projects.

How to Migrate From Pages Router to App Router in NextJS [Part 1].

Photo by Kaleidico on Unsplash

The app router on NextJS was first introduced in NextJS13, which was in beta back then. At the moment of writing this article, the current major version of NextJs is 14, and the app router has become stable, with more and more neat features coming along. While the old page router is still active and maintainable I’d strongly encourage you to consider app router migration because the pages router most likely won’t get any features soon.

I’ve recently done the app router migration for several projects and I’d like to share my thoughts, best practices and ideas. The guide will be split into 2 parts.

The first part (the current one) will consider:

  • app router structure;
  • updates for useRouter hook;
  • metadata updates;
  • data fetching;

The second chapter will consist of:

  • error handling;
  • loading UI and streaming;
  • styling (Material UI);
  • 3rd party libraries;
  • lazy loading;
  • sitemap;

Interested? Let’s then jump straight into action!

From Where to Start The Actual Migration?

Split the migration into smaller steps. The app directory is intentionally designed to work simultaneously with the pages directory to allow for incremental page-by-page migration.

So I’d suggest the following migration guide:

  • create the /app folder with the layout.tsx — it’s going to be the root layout that replaces _appand _document ;
  • migrate the React context providers (if any);
  • migrate the router hook from next/router to next/navigation (and use additional routing hooks which come as separate modules);
  • update metadata;
  • start migrating page-by-page, split down server/client components, and update the data fetching;

Step 1: The /app Folder and its structure

The App Router works in a new directory named app.

By default, components inside app are React Server Components. This is a performance optimization and allows you to easily adopt them, and you can also use Client Components.

You can choose between creating a new app directory at the root of your project or inside src/ directory based on your preferences.

Folders are used to define routes. A route is a single path of nested folders, following the file-system hierarchy from the root folder down to a child page (leaf) folder that includes a page.js file.

The difference in structuring page routes

So, what we are doing first is creating the app folder and defining the root layout. Since the app directory must include a root layout.

  • The root layout must define <html>, and <body> tags since Next.js does not automatically create them;
  • The root layout replaces the pages/_app.tsx and pages/_document.tsx files;

Great, we’ve just defined the root layout. Now, if you have an existing _app or _document file, you can copy the contents (e.g. global styles, context providers) to the root layout (app/layout.tsx). Styles in app/layout.tsx will not apply to pages/*. You should keep _app/_document while migrating to prevent your pages/* routes from breaking. Once fully migrated, you can then safely delete them.

⚠️ If you are using React context prodivers in your old application you will face errors when trying just copy and paste them. It’s because components inside the app directory are server components by default, and React Context is the client API. So you’d need to do the following: 1. Define the new file (for example /app/context.tsx 2. Make it client component by writing use client; at the very top;

And then wrap your root layout:

Done!

The next step is to update the router hook usage.

Step 2: updates for useRouter hook

  • The useRouter hook should be imported from next/navigation and not next/router when using the App Router
  • The pathname string has been removed and is replaced by usePathname()
  • The query object has been removed and is replaced by useSearchParams()
  • router.events has been replaced.

Step 3: Migrating Pages

Before making the pages migration here; 's the important note:

Pages in the app directory are Server Components by default. This is different from the pages directory where pages are Client Components. Also, data fetching for pages defined in app router has changed: getServerSideProps, getStaticProps and getInitialProps have been replaced with a simpler API.

So there are 2 ways of doing the pages migration: 1. Move the page to the app router and make it server component from the very beginning (more complex approach for smaller projects); 2. Move the default exported Page Component into a new Client Component and then import that into a new page.js file inside the app directory. (the easiest approach is suitable for large projects, which will also allow you to optimize each page separately by making it Server component).

Here’s the example of the second approach (assuming you have /about page in the old pages router):

Creating a new separate file inside the app directory. It receives data as props just like Page components.

Create a new app/about/page.tsx file inside the app directory. This is a Server Component by default. Then import your client component into that page. If you were fetching data in the old page, move the data fetching logic directly into the Server Component with the new API.

Step 4: Metadata Updates

The old <Head /> component has been replaced with Metadata API.

So the new way of defining metadata is by exporting the Metadata object like this:

You can find all the available metadata fields here. Also, there is the file-based metadata, which allows you to generate special metadata files (like favicon, robots.txt, etc.)

Please note that there is an option to generate dynamic metadata if needed

Data Fetching options and caching

To start with, there are 4 ways of fetching the data:

  1. On the server, with fetch
  2. On the server, with third-party libraries
  3. On the client, via a Route Handler
  4. On the client, with third-party libraries.

Whenever possible, it’s recommended fetching data on the server with Server Components. This will allow you to have direct access to backend data resources, keep your application more secure by preventing sensitive information, fetch data and render in the same environment. This reduces both the back-and-forth communication between client and server, as well as the work on the main thread on the client.

Caching

Next.js extends the native fetch Web API to allow you to configure the caching and revalidating behavior for each fetch request on the server. React extends fetch to automatically memoize fetch requests while rendering a React component tree.

In case you are using any 3rd party libraries for the data fetching it’s recommended to use React cache util.

Conclusion

In conclusion, migrating from the Pages Router to the App Router in Next.js can significantly improve the performance and maintainability of your projects. As the App Router has become stable and continues to receive updates, it is a wise choice to consider this migration for your Next.js applications. This article has provided an overview of the steps involved in the migration process, including creating the app folder, updating the router hook, migrating pages, and making metadata updates. The second part of this guide will cover additional aspects such as error handling, styling, and lazy loading. By following these best practices and ideas, you can ensure a smooth transition to the App Router and take advantage of its benefits in your Next.js projects. Stay tuned for Part 2 to explore further details and optimizations for your application. Happy coding!

Nextjs
Nextjs Tutorial
React
Reactjs
Nextjs App Router
Recommended from ReadMedium