개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Next.js App Router — 파일 시스템 기반 최신 라우팅

2025년 5월 6일
Next.jsApp RouterFile System Routinglayout.tsxpage.tsx

Next.js 13부터 도입된 App Router는 pages/ 디렉터리 방식을 대체하는 새로운 라우팅 패러다임이다. 디렉터리 구조 자체가 URL 경로가 되고, 특수 파일명이 각 역할을 담당하는 방식으로 작동한다. 한 번 익히면 레이아웃 중첩, 로딩 상태, 에러 처리를 선언적으로 구성할 수 있다.

App Router 디렉터리 구조

app/
├── layout.tsx          ← 루트 레이아웃 (필수)
├── page.tsx            ← "/" 경로
├── loading.tsx         ← 루트 로딩 UI
├── error.tsx           ← 루트 에러 UI
├── not-found.tsx       ← 404 페이지
└── dashboard/
    ├── layout.tsx      ← /dashboard/* 공통 레이아웃
    ├── page.tsx        ← "/dashboard" 경로
    └── settings/
        └── page.tsx    ← "/dashboard/settings" 경로

각 디렉터리가 URL 세그먼트에 대응하며, 특수 파일들이 해당 세그먼트의 동작을 정의한다.

특수 파일 역할 비교

파일명역할필수 여부
page.tsx해당 경로의 UI필수
layout.tsx하위 경로 공통 래퍼선택
loading.tsxSuspense 로딩 UI선택
error.tsx에러 바운더리 UI선택
not-found.tsx404 UI선택

layout.tsx — 중첩 레이아웃

layout.tsx는 같은 디렉터리와 그 하위 경로 전체를 감싸는 래퍼다. 페이지 이동 시 리렌더링 없이 유지된다.

// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ko">
      <body>
        <nav>글로벌 내비게이션</nav>
        {children}
      </body>
    </html>
  );
}

layout.tsx: children으로 하위 페이지를 받아 렌더링하는 컴포넌트. 루트 레이아웃은 <html>과 <body> 태그를 반드시 포함해야 한다.

중첩 레이아웃은 자동으로 조합된다.

RootLayout (app/layout.tsx)
└── DashboardLayout (app/dashboard/layout.tsx)
    └── SettingsPage (app/dashboard/settings/page.tsx)

loading.tsx — 자동 Suspense 처리

loading.tsx를 추가하면 Next.js가 해당 page.tsx를 자동으로 <Suspense>로 감싼다. 별도 설정 없이 스트리밍 로딩 UI가 동작한다.

// app/dashboard/loading.tsx
export default function DashboardLoading() {
  return <div>대시보드 불러오는 중...</div>;
}

error.tsx — 에러 바운더리

error.tsx는 클라이언트 컴포넌트("use client")여야 하며, 하위 트리에서 발생한 에러를 잡아 대체 UI를 표시한다.

// app/dashboard/error.tsx
"use client";

export default function DashboardError({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  return (
    <div>
      <p>오류 발생: {error.message}</p>
      <button onClick={reset}>다시 시도</button>
    </div>
  );
}

reset: Next.js가 주입하는 함수로, 에러가 발생한 세그먼트를 다시 렌더링 시도한다.

동적 경로 세그먼트

대괄호 디렉터리명으로 동적 파라미터를 선언한다.

// app/posts/[slug]/page.tsx
export default function PostPage({
  params,
}: {
  params: { slug: string };
}) {
  return <h1>포스트: {params.slug}</h1>;
}

app/posts/hello-world로 접근하면 params.slug는 "hello-world"가 된다.

라우팅 흐름 요약

요청 URL: /dashboard/settings
          │
          ▼
app/layout.tsx          (루트 레이아웃 적용)
          │
          ▼
app/dashboard/layout.tsx (대시보드 레이아웃 적용)
          │
          ▼
app/dashboard/settings/page.tsx (페이지 렌더링)

App Router는 레이아웃 중첩, 로딩/에러 처리, 동적 경로를 모두 파일 시스템 규칙으로 표현한다. 별도 라우터 설정 없이 디렉터리 구조만으로 복잡한 라우팅 요구사항을 충족할 수 있다.

← 이전 글Next.js란? — React 위에 올린 풀스택 웹 프레임워크
다음 글 →Next.js Routing — 파일 경로가 URL이 되는 방식