Choose Your Own Adventure: NEXT.js App vs. Pages Router

Jawara Gordon
7 min readOct 1, 2023

--

“Next.js is a React framework for building full-stack web applications.” — NEXTjs.org

What is Next.js?

In the crowded JavaScript framework space, Next.js stands out from the crowd. This streamlined tool allows developers to create modern web applications quickly and efficiently.

Imagine combining the power of React, with the added bonus of server-side rendering and static site generation. The beauty of Next.js lies in its simplicity, enabling developers to focus on what truly matters — creating exceptional user experiences. Whether you’re building a personal blog or a dynamic enterprise application, Next.js will transform your coding journey from an uphill battle to a fun-filled adventure!

Let’s dive into a brief history of Next.js, build a new app from scratch, and decide which routing option works best for your next project.

A Fork In The Road

Rooted in the need for better performance, scalability, and efficiency, Next.js was introduced in October 2016 by Vercel (formerly known as Zeit). This lightweight framework was designed with an emphasis on convention over configuration. Next’s out-of-the-box server-side rendering, routing, and tooling is a direct response to the challenges faced in single-page applications (SPAs), such as SEO optimization, load times, and code splitting.

By addressing these issues, Next.js continues to gain popularity within the React community while contining to adapt to the ever-changing landscape of web development.

Photo by Maria Teneva on Unsplash

Getting Started

This guide assumes you’re familiar with using command line tools along with having a basic understanding of Node.js, React, and vanilla JavaScript.

Installation

Next.js can be completely bootstrapped through an automatic installation process called `create-next-app`.

To create a new project, run this command in your terminal:


$ npx create-next-app@latest

You’ll see the following prompts:


What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
What import alias would you like configured? @/*

Choose the prompts that work best for you and remember — you can always add more dependencies later. Next.js ships with TypeScript, ESLint, and Tailwind CSS by default in addition to an optional `src` directory to separate application code from configuration files.

Note: This example uses TypeScript, however replacing .tsx with .js will yield the same results.

Create-next-app will generate a folder with your project name and install the required dependencies.

You also have the option to do a manual installation.

To install manually, add these packages:


$ npm install next@latest react@latest react-dom@latest

Open your `package.json` file and add the following scripts:


{
“scripts”: {
“dev”: “next dev”,
“build”: “next build”,
“start”: “next start”,
“lint”: “next lint”
}
}

These scripts refer to different stages of your development cycle:

  • `dev`: runs `next dev` to start Next.js in development mode.
  • `build`: runs `next build` to build the application for production usage.
  • `start`: runs `next start` to start a Next.js production server.
  • `lint`: runs `next lint` to set up Next.js’ built-in ESLint configuration.

Project Structure

Next.js uses file-system routing, which means the routes in your application are determined by how you structure your files. This convention requires you to make a big decision at the start of any new project. App Router vs. Pages Router — which one should you choose?

Let’s take a closer look at the pros and cons of each, and what this means for your application:

App Router

The App Router is Next.js’s answer to advanced routing needs, allowing for more complex patterns and setups.

Structure:

Introducing a shift away from traditional structures, app router adopts a more modular and organized directory approach:

└── app
├── about
│ └── page.tsx
├── globals.css
├── layout.tsx
├── login
│ └── page.tsx
├── page.js
└── team
└── route.tsx

Features:

  1. Client and Server Components: Allows differentiation between components that run on the server versus the client. This offers greater optimization, especially when dealing with server-side operations versus client-side interactivity.
  2. Easy Layouts: With `layout.js`, managing layouts becomes easier and more intuitive. Nested layouts further simplify hierarchical page structures.
  3. Server Actions: This feature lets you execute server-side code based on client-side events.
  4. Intercepting Routes: Provides a mechanism to render different components based on conditions, even if the URL remains the same.
  5. Parallel Routing: Lets you render multiple pages on the same URL, enhancing flexibility.
  6. Built-in SEO: App router introduces a built-in approach to handling metadata, making the `next/head` redundant.

Pros

  • Flexibility: Adapt to a wide range of routing scenarios.
  • Dynamic Data Handling: Seamlessly integrates with varying data sources.

Cons

  • Learning Curve: Might be overwhelming for beginners.
  • Optimization: Requires additional efforts to ensure best performance.

Pages Router

The Pages Routing system is both intuitive and effective. By adding React components to the `pages` directory, routes are automatically established.

Structure:

Historically Next.js used the `pages` directory to automatically generate routes based on the filenames:

└── pages
├── about.tsx
├── index.tsx
└── team.tsx

Features:

  1. Automatic Routes: Adding a `.js` or `.tsx` file to the `pages` directory automatically creates a route.
  2. SEO Optimization:With the `next/head` component, SEO optimization was straightforward.
  3. Data Fetching Methods: Included `getStaticProps`, `getServerSideProps`, and `getStaticPaths` for fetching data.
  4. Custom Document & App Component: Allowed for customization of the overall document structure and layout.

Pros

  • Efficiency: Next.js streamlines the development process, saving time.
  • SEO Ready: With server-side rendering, content is ready for both users and search engines.

Cons

  • Complex Routes: Might not be ideal for intricate routing needs.
  • Naming Convention: The structure is tied to file and folder names, demanding accurate naming.
Photo by Paulo Silva on Unsplash

Making A Decision

So, how do you decide which way to go and what’s right for your project?

“For new applications, we recommend using the App Router.” — NEXTjs.org

The Next.js team has clearly gone all-in on app router — but consider the following before making a decision:

Project scope: Is it a minimalistic blog or a multifaceted e-commerce platform?

Scalability: Factor in future growth and scaling needs.

“The Pages Router is the original Next.js router, […] and continues to be supported for older Next.js applications.” — NEXTjs.org

Your routing choice today can and will influence your project’s evolution so choose wisely!

App Router

Here’s how to get started using ‘app router’.

Create an `app/` folder, then add a `layout.tsx` and `page.tsx` file:


// app/layout.tsx

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
// app/page.tsx
export default function Page() {
return <h1>Hello, Next.js!</h1>;
}

If you forget to create `layout.tsx`, Next.js will automatically add this file when running the development server with `next dev`.

Pages Router

If you prefer to use the Pages Router, you should create a `pages/` directory at the root of your project.


// pages/index.tsx

export default function Page() {
return <h1>Hello, Next.js!</h1>;
}
// pages/_app.tsx
import type { AppProps } from 'next/app'

export default function App({ Component, pageProps }: AppProps) {
return <Component {…pageProps} />;
}
// pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}

Pro Tip:
You can use both routers in the same project with `app` routes prioritized over `pages` — but it’s recommend to use only one to avoid confusion.

Final Steps

Create a `public` folder to store static assets such as images, fonts, etc. Files inside the `public` directory can then be referenced by your code starting from the base URL.

Additional folders dynamic routes and config files can be added to the project structure by referencing this list: Project Structure

Run the Development Server

To see all your work come to life, run:

$ npm run dev

Visit [http://localhost:3000](http://localhost:3000) to view your application.

Edit `app/layout.tsx` (or `pages/index.tsx`) to see your changes compile in your browser.

Success!

Photo by Benjamin Davies on Unsplash

The Path Forward

App Router introduces a significant evolution in the Next.js framework, offering advanced features and enhanced flexibility. While the Pages Router will remain sufficient for many applications, the recommended App Router’s capabilities offer greater control and functionality.

Keep in mind, choosing between the two routers isn’t about “right” or “wrong” but about what best fits your project’s needs. Whether you’re new to Next.js or an experienced user looking to adapt the latest features, this guide aims to point you in the right direction for your next project!

Sources:

- https://nextjs.org/blog/next-2-0
- https://vercel.com
- https://nextjs.org/docs

--

--

Jawara Gordon

Jawara (jah-WAH-rah): Full-Stack Web Developer | Audio Engineer JavaScript, React, HTML, CSS/SASS, Ruby on Rails | Ableton Live