Next.js 13부터 도입된 App Router는 pages/ 디렉터리 방식을 대체하는 새로운 라우팅 패러다임이다. 디렉터리 구조 자체가 URL 경로가 되고, 특수 파일명이 각 역할을 담당하는 방식으로 작동한다. 한 번 익히면 레이아웃 중첩, 로딩 상태, 에러 처리를 선언적으로 구성할 수 있다.
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.tsx | Suspense 로딩 UI | 선택 |
error.tsx | 에러 바운더리 UI | 선택 |
not-found.tsx | 404 UI | 선택 |
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를 추가하면 Next.js가 해당 page.tsx를 자동으로 <Suspense>로 감싼다. 별도 설정 없이 스트리밍 로딩 UI가 동작한다.
// app/dashboard/loading.tsx
export default function DashboardLoading() {
return <div>대시보드 불러오는 중...</div>;
}
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는 레이아웃 중첩, 로딩/에러 처리, 동적 경로를 모두 파일 시스템 규칙으로 표현한다. 별도 라우터 설정 없이 디렉터리 구조만으로 복잡한 라우팅 요구사항을 충족할 수 있다.