[Next.js] App Router vs Page Router

김수연·2025년 5월 1일

Next.js

목록 보기
1/2
post-thumbnail

Next.js는 React 기반의 프레임워크로, React에서는 react-route-dom을 설치하고, 컴포넌트를 이용해 라우트를 수동으로 설정해야 하는 것과 달리, 파일 기반의 자동 라우팅 시스템을 기본으로 제공한다.
Next.js 13 이전까지는 pages/ 디렉토리를 이용한 Pages Router 방식이 표준이었지만,
13버전 이후부터는 app/ 디렉토리를 사용하는 App Router가 도입되어 새로운 아키텍처가 가능해졌다.

이번 글에서는 Pages Router와 App Router의 차이를 구조, 기능, 사용 방식 측면에서 자세히 비교해보고, 어떤 상황에서 어떤 방식을 사용하는 것이 좋은지 알아보자.


1. 라우팅 방식의 구조적 차이

Pages Router

  • pages/ 폴더에 있는 파일이 URL 경로와 자동으로 매핑된다.
  • 구조가 단순하고 직관적이어서 학습하기 쉽다.
pages/
├── index.js       → /
├── about.js       → /about
└── blog/
    └── [id].js    → /blog/:id
  • 라우팅은 파일 이름 기반으로 결정된다.
  • 커스텀 레이아웃을 사용하려면 _app.js, _document.js 등을 활용해야 한다.

App Router

  • app/ 폴더를 기반으로 하며, 폴더와 파일의 조합으로 라우팅을 정의한다.
  • 페이지마다 별도 page.js, layout.js, loading.js, error.js 등을 지정할 수 있다.
app/
├── layout.js            → 전체 레이아웃
├── page.js              → /
├── about/
│   └── page.js          → /about
└── blog/
    └── [id]/
        └── page.js      → /blog/:id
  • 중첩 폴더 구조를 통해 라우팅 및 레이아웃의 계층화를 명확히 할 수 있다.
  • 최신 React 기능(서버 컴포넌트, 스트리밍 등)이 기본 내장되어 있다.

2. 레이아웃 처리 방식의 차이

Pages Router의 _app.js

  • pages/_app.js는 앱 전체에 공통되는 컴포넌트를 정의하는 역할을 한다.
  • 모든 페이지는 _app.js에서 정의한 컴포넌트로 감싸져 렌더링된다.
  • 다음과 같이 활용할 수 있다.
// pages/_app.js
import Layout from '../components/Layout';

function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}
  • 단점은 페이지별로 다른 레이아웃을 적용하기 어렵다는 점이다.
  • 모든 페이지에 같은 레이아웃이 강제되기 때문에 중첩 레이아웃 구성에 제약이 있다.

App Router의 layout.js

  • app/layout.js는 App Router에서 각 페이지마다 레이아웃을 정의할 수 있도록 도와주는 핵심 파일이다.
  • 폴더 단위로 레이아웃을 설정할 수 있으며, 중첩 구조가 가능하다.
// app/dashboard/layout.js
export default function DashboardLayout({ children }) {
  return (
    <div className="dashboard-layout">
      <Sidebar />
      <main>{children}</main>
    </div>
  );
}
  • 특정 경로 하위에서만 다른 레이아웃을 사용하는 것도 가능하다.
  • 코드 재사용성과 유지보수성이 향상된다.

3. 서버 컴포넌트 및 스트리밍 지원 여부

기능Pages RouterApp Router
서버 컴포넌트❌ 미지원✅ 기본 지원
클라이언트 컴포넌트 분리❌ 불가능use client 선언으로 명시
스트리밍 렌더링❌ 미지원loading.js 등으로 지원

App Router에서는 서버 컴포넌트를 기본적으로 지원하기 때문에, 클라이언트로 전달되는 JavaScript 양을 줄여 초기 렌더링 성능을 개선할 수 있다.
또한, React 18의 Concurrent Feature와 결합하여 스트리밍 방식으로 페이지를 순차적으로 렌더링할 수 있다.


4. 데이터 패칭 방식

Pages Router

  • getStaticProps, getServerSideProps, getInitialProps 같은 특수한 함수들을 사용해야 한다.
  • 함수는 페이지 컴포넌트에 직접 정의되어야 하며, 컴포넌트 내부에서는 사용이 불가능하다.
export async function getStaticProps() {
  const res = await fetch('...');
  const data = await res.json();

  return {
    props: { data },
  };
}

App Router

  • 서버 컴포넌트 내부에서 fetch() 호출이 가능하다.
  • React의 컴포넌트 스타일을 그대로 유지하면서도 데이터를 패칭할 수 있다.
// app/products/page.js
export default async function ProductsPage() {
  const res = await fetch('https://api.example.com/products');
  const data = await res.json();

  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}
  • API 호출 시 Suspense와 결합해 비동기 UI를 자연스럽게 구성할 수 있다.

5. 마이그레이션

Next.js는 Pages Router와 App Router를 동시에 사용할 수 있도록 설계되어 있다.
따라서 완전히 이전하지 않고도 점진적으로 App Router로 옮길 수 있다.

마이그레이션 시 체크리스트

  • Node.js 버전: 최소 18.17 이상
  • React 버전: 18 이상 필수
  • ESLint와 Prettier 등 툴 설정 최신화
  • app/ 디렉토리 도입 후 기존 pages/와 병행 구성
  • 각 경로에 맞는 layout.js, page.js, error.js, loading.js 등 구성 규칙 숙지 필요

6. 어떤 것을 써야 할까?

상황추천 라우팅 방식
새로운 프로젝트✅ App Router
기존 Pages Router 프로젝트 유지보수✅ 병행 또는 점진적 이전
SSR 기능 위주 프로젝트✅ App Router (서버 컴포넌트 활용 가능)
단순한 정적 사이트✅ Pages Router도 무방

App Router는 Next.js의 미래 지향적인 방향이자 핵심 기능을 담고 있는 구조이기 때문에, 새롭게 시작하는 프로젝트라면 App Router를 선택하는 것을 추천한다.
단, 복잡할 수 있기 때문에, 공식 문서를 참고하면서 천천히 익혀가는 것이 좋을 것 같다.


마치며

초기에는 App Router가 생소하고 복잡해 보일 수 있지만, 익숙해지면 더 깔끔하고 확장 가능한 코드를 구성할 수 있다.

향후 Next.js는 App Router를 중심으로 발전해 나갈 것으로 보이기 때문에, 지금부터 천천히 익혀두는 것이 좋은 선택이 될 것이다.


참고자료

profile
프론트엔드 공부하는 학생입니다

0개의 댓글