Pages Router vs App Router in Next.js - Key Differences

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Around in May 2023, Next.js witnessed some big changes with the introduction of the new App Router. Just prior to that, I had created a video series showing how to build a headless blog with Next.js as the frontend and WordPress as the API. It was based on the previous `pages`router. Many people started asking how to make the project work with the new app router. So I rebuilt the entire project using app router. If you want to check that out, you can find the code in my GitHub repository. In this video, we will discuss the important things to keep in mind while making the transition, for any existing or new Next.js project. The first thing I want to tell you is that the old **Pages Router** still works. Next.js hasn't yet removed support for it in the latest versions. You can still find the documentation for the Pagees router on Nextjs website You can continue developing in the old way as if nothing has happened. If you have apps in production that uses Pages Router, no need to switch in a hurry. However, it looks like **App Router** is the way forward. So they might remove support for the Pages Router in the future. I don't know. Also `/pages` and `/app` directories can co-exist within the same project. Some pages can be within the old `/pages` directory, while some can be within the `/app` directory. So you can move pages incrementally. However, the same page cannot exist inside `/pages` and `/app` simultaneously. 2. The next major change is regarding how you name the routes The Pages Router followed a file and folder based routing. For instance, if you have a route location `example.com/members/list`, then you define it inside `/pages/members/list.js`. That has changed with the new App Router. All routes are identified with the name of the folder in which it exists. So the same example becomes: `/app/members/list/page.js`. Note that `list` is a folder which identifies the route path, within which we define the file `page.js`. Here, `page.js` is a reserved file name in the Next.js App Router, which is used to export the page component for any route. For instance if you have another route like `example.com/blog/my-post`, you can define it as: `/app/blog/[slug]/page.js`. In effect, you end up having a `page.js` inside each route folder. So if your app has 10 routes, then you will have 10 `page.js` files nested within the `/app` directory. That's one thing I don't quite like with the new approach - with more than one file with identical file name, the `/app` directory can look quite a mess if your app has a few dozen routes. The problem exacerbates when considering that `page.js` is not the only reserved file name. You can also have nested `layout.js` files, `route.js` files for defining API routes, and so on. [**3. `_app.js` and `_document.js` gone**](#) With `/pages`, you can use `_app.js` and `_document.js` files to define custom app and custom document structures. Moving to the App Router, both of these are replaced by `layout` files - `layout.js` (`.jsx` or `.tsx`). As I already mentioned, `layout` is another reserved file name. Layouts can be placed alongside `page.js` files inside route folders. You can also have multiple levels of nested layouts, which means there can be a parent layout file in the root directory with sub-layouts inside route folders. Want to import global stylesheets? You can do that within the root layout. Also, `layout` takes the inner layouts and pages as its children. So the root layout file (`/app/layout.js`) is a must-have. I think this move has simplified the layout arrangement when compared to the previous `_app` and `_document` based arrangement. [**4. Data Fetching**](#) Another notable change is with regards to how you fetch external data within pages and API routes. In the Pages Router, there were two functions: `getStaticProps()`, and `getServerSideProps()` Both functions run on the server during build time, or during server-side rendering, depending on whether you're using SSG or SSR respectively. Within these functions, you could perform fetch requests and return the results. And the returned values would be available to the default export function as props. Now, both these functions are completely gone in App Router. Instead, you can directly use the Fetch API - `fetch()` - that we're already used to. No need to put them inside special functions like `getStaticProps()` or `getServerSideProps()`. Since all components are server-side by default in the App router (more on that below), you can rest assured that the `fetch()` happens on the server and not on the client. [**5. Static Site Generation**](#) In Pages Router, when you want to statically generate dynamic routes, you could return an array of route path values from the `getStaticPaths()` function. Now this function name is changed to `generateStaticParams()`. Next.js says that this function name looks more meaningful. Also note that the structure of the return object is also simplified. No need for the `fallback` property either. [**6. SEO**](#) In my opinion, SEO was a bit of a mess in the `pages` router. You had to fetch and return all seo tags inside `getStaticProps()` or `getServerSideProps()`, then insert it inside `<Head />` components appropriately.Instead of that, App Router has built-in support for SEO. you can export a const object called `metadata`, which contains the title, description, open graph tags, and so on or if you want to generate these values dynamically, define a function called `generateMetadata()`, which then fetches all the values and returns the object Next.js will automatically insert these metadata values within the `<head>` tag during build or render time. [**API Routes**](#) In the `/pages` router, all API routes were defined within the `/api/` folder. And each API route file exported a function named `handler(req, res)`. Now, there are no restrictions like that. You can create API routes in any folder, not just the `/api/` folder. Make sure to name the API route files as `route.js`. That's how they differ from other `page.js` routes and `layout.js` files. Here note that `route.js` is another reserved file name. The handler function has also changed. Now you can denote the request method by the function name - like: GET, POST, PUT, DELETE, etc Next.js has also made available the `NextRequest` and `NextResponse` objects, which are extended from the native Request and Response objects available with the JavaScript Fetch API. Overall, the API feature has become more powerful with the new `/app/` router. [**Revalidation & Caching Behaviour**](#) In the Pages Router, you could set the `revalidate` property inside `getStaticProps()` to tell Next.js how often to fetch the latest data from the source. Else if you wanted to fetch the data on every request, `getServerSideProps()` should be used instead of `getStaticProps()`. There was also a `fallback` property alongside `revalidate` that dictates when to run the `getStaticProps()` function. Now all these confusions are gone! All data fetches are cached by default, when used with the `fetch()` function. The cache persists infinitely if no other options are used. If you want to completely opt-out of cache, add the option `{ cache: 'no-store' }` to `fetch()`. This makes it equivalent to using `getServerSideProps()` - fresh data is fetched on every request. Data can also be re-fetched periodically - add the `revalidate` option. For instance `{ revalidate: 3600 }` fetches fresh data at most every one hour. [**Server Components & Client Components**](#) The new React Server Components is what everyone is talking about now. At first, I couldn't wrap my head around it. *Next.js already renders React components on the server, right? Then how does it make sense? That was my initial thought.* Anyways, here is what I've understood so far. The concept is still a bit confusing to me. In the Pages Router, all components are client components, you can't create server components. Whereas in the App Router all components are Server Components by default. However you can create client components by adding the 'use client' directive at the top. But don't get confused by the term 'client component'. A Client Component gets rendered on the server and on the client, or in other words, hydrated on the client. With hydration, the components are sent to the client and made interactive. So you can use effects, state data, and other interactivity. Whereas a Server Component is rendered on the server-only. It's not sent to the client or hydrated. Hence it will be non-interactive - state, useEffect, etc won't work. The advantages: lesser bundle size, data fetching and processing happens entirely on the server. That's the difference. Let's take an example: consider there is a component like this in the App Router this button's onClick won't trigger because it is inside a serve component. **So, how to make it interactive?** That's where you can use Client Components. **But how to create a client component?** So when you want interactivity, move that part to a child component, then switch to 'client mode' by adding the `use client` directive at the top. Make sure to add the directive at the top of the file. The `use client` directive marks all the components in that file as Client Components. Also if you import components into a client component, they will also function as client components. In effect, the 'use client' directive works like a boundary between server components at the top and client components below. then import it inside the parent server component Now this button's onClick event will work. However, the opposite is not possible. You can't import a server component into a client component. Some features, like the SEO `metadata` we discussed above, can only be used inside a server component. Also, data fetching should also be performed inside server components, because it is often closer to the data source I'm still learning about the new features in Next.js, so if there is anything incorrect in what I've presented, kindly point out. Hope this video was useful for you, thanks for watching.
Info
Channel: Coding Reflections
Views: 3,372
Rating: undefined out of 5
Keywords: nextjs tutorial, next js, next js app router
Id: GJPEgai_dKw
Channel Id: undefined
Length: 12min 24sec (744 seconds)
Published: Fri Sep 29 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.