Contents
see List작성일 2025. 11. 30.
Next.js App Router 마이그레이션 가이드
Next.js 12/13 Pages Router에서 App Router로 마이그레이션하는 가이드입니다.
App Router 디렉토리 구조
app/
layout.tsx # 루트 레이아웃 (필수)
page.tsx # 루트 페이지 (/)
loading.tsx # 로딩 UI
error.tsx # 에러 핸들링
not-found.tsx # 404 페이지
dashboard/
layout.tsx # 중첩 레이아웃
page.tsx # /dashboard 페이지
blog/
[slug]/
page.tsx # 동적 라우팅Pages → App Router 변환
// Pages Router (pages/index.tsx)
export default function Home() {
return <div>Home</div>;
}
// App Router (app/page.tsx)
export default function Home() {
return <div>Home</div>;
}Layout 설정
// app/layout.tsx (필수)
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ko">
<body>
<header>헤더</header>
<main>{children}</main>
<footer>푸터</footer>
</body>
</html>
);
}데이터 페칭 변경
// Pages Router - getServerSideProps
export async function getServerSideProps() {
const data = await fetch("...");
return { props: { data } };
}
// App Router - 서버 컴포넌트에서 직접 fetch
async function Page() {
const data = await fetch("...", { cache: "no-store" });
return <div>{data}</div>;
}
// App Router - 정적 생성 (getStaticProps 대체)
async function Page() {
const data = await fetch("...", { cache: "force-cache" });
return <div>{data}</div>;
}클라이언트 컴포넌트
// 상단에 "use client" 지시어 필요
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}메타데이터 설정
// Pages Router - Head 컴포넌트
import Head from "next/head";
<Head><title>페이지 제목</title></Head>
// App Router - metadata 객체
export const metadata = {
title: "페이지 제목",
description: "페이지 설명",
};
// 동적 메타데이터
export async function generateMetadata({ params }) {
return { title: params.slug };
}라우팅 차이점
| 기능 | Pages Router | App Router |
|---|---|---|
| 동적 라우트 | [id].tsx | [id]/page.tsx |
| 레이아웃 | _app.tsx | layout.tsx |
| 에러 | _error.tsx | error.tsx |
| 404 | 404.tsx | not-found.tsx |
마이그레이션 팁
- 점진적 마이그레이션 가능 (pages/와 app/ 공존)
- 서버 컴포넌트가 기본값
- 상태/이벤트 사용 시 "use client" 필요
javascript
| No | 작성일 | Title |
|---|---|---|
| 3384 | 2026. 08. 21. | Node.js API에서 요청 취소를 제대로 처리하는 방법: AbortSignal로 외부 작업 정리하기 |
| 3352 | 2026. 08. 13. | Node.js 응답이 간헐적으로 느릴 때: 이벤트 루프 지연 측정과 CPU 작업 분리 방법 |
| 3320 | 2026. 08. 04. | JavaScript fetch 요청을 안전하게 만드는 방법: timeout·재시도·오류 처리 실전 패턴 |
| 3288 | 2026. 07. 27. | Node.js 서버 무중단 배포를 위한 Graceful Shutdown 구현 가이드 |
| 3257 | 2026. 07. 19. | Node.js 대용량 파일 처리 가이드: 스트림과 backpressure로 메모리 사용량 제어하기 |
| 3232 | 2026. 07. 11. | Node.js 실무형 에러 처리: async/await에서 실패를 일관되게 분류하고 복구 속도 높이기 |
| 3174 | 2026. 07. 02. | Node.js 환경 변수 검증 가이드: process.env를 안전한 설정 객체로 바꾸기 |
| 3123 | 2026. 06. 24. | TypeScript 타입 좁히기 운영 가이드: unknown 입력을 안전한 도메인 객체로 바꾸기 |
| 3065 | 2026. 06. 16. | 브라우저 성능 병목 찾기: PerformanceObserver로 LCP·INP·긴 작업 로그 수집하기 |
| 2978 | 2026. 06. 08. | Node.js fetch 타임아웃과 재시도 설계: 외부 API 장애 전파 줄이기 |