Next.js 13 App Router vs Pages Directory - Pros & Cons
May 23, 2023 by Florian
For the last week or so, I've been refactoring some of my Next.js code from the pages directory to the new app router, which is now stable.
In case you don't know, the app router is a new way of structuring Next.js projects. It harnesses new React features like server components and suspense boundaries and got rid of getServerSideProps and getStaticProps.
If all of this sounds new to you, don't worry. I just released an updated Next.js 13 app router tutorial on my Youtube channel where you will learn these new Next.js features from scratch. For comparison, here is my old Next.js tutorial that uses the pages directory.
I'm also adding a new section to my Full-Stack Next.js With Express and Typescript Course soon, where we refactor the project from the pages directory to the new app router. This is especially cool because you will learn both approaches and how they relate to each other.
My experience so far
In this post, I want to summarize a few of my observations and problems while refactoring my Next.js projects to the new app router. This will help you decide which approach you should use going forward.
👍 Pros of the new app router:
-
Fetching data server-side is a bit more intuitive and simpler now compared to
getStaticProps
andgetServerSideProps
in the pages directory. You just fetch data in async component functions and don't need to return weird object types anymore. -
The new React server components can make your apps faster because they are fully rendered on the server and don't require any JavaScript to be sent to the browser. I haven't observed any noticeable differences in my own projects yet but at least that's the theory.
-
You get more fine control over how single components fetch and cache data, rather than having to decide for the whole page at once.
-
You can put other files, like CSS modules and components, into the app directory. This colocation of files improves the organization of your project.
-
Building more complex layouts with shared elements and different loading & error states is easier now thanks to
layout.tsx
,loading.tsx
, anderror.tsx
.
👎 Cons of the new app directory:
-
Some features are still missing. For example, shallow routing and router events are not supported yet. This makes some app features I had previously implemented now impossible.
-
There are quite a few significant bugs, like loading states getting stuck or pages not updating when they should.
-
There are several configuration options that effectively to the same thing (like deciding how to cache data) which can be confusing.
-
And probably the most common complaint so far: The client-side router cache caches even dynamically rendered server pages so that you don't see the latest updates when you navigate back and forth between pages. This can cause stale data to be shown.
In summary, while I think the new app router is great and will be an upgrade from the current approach, I recommend you stick to the pages directory for production apps for the next few months. I personally have filed several bug reports already and I'm waiting for them to get fixed.
I'm just the Next.js team will fix many of these problems over the next months!
If you like this post, make sure to sign up for my email newsletter. I send regular posts like these, as well as shorter tips and updates on my latest web dev tutorials.
Happy coding and take care!
Florian
Tip: I send regular high-quality web development content to my free email newsletter. It's a great way to improve your skills and stay ahead of the curve.
Subscribe Now