기술 트렌드2023-08-05 (토요일)
Next.js Pages에서 App Router로 마이그레이션하기
김개발•10분 읽기
Next.js Pages에서 App Router로 마이그레이션하기
Next.js 13에서 도입된 App Router는 더 강력한 라우팅 기능과 React 서버 컴포넌트를 활용할 수 있는 새로운 방식을 제공합니다. 이 글에서는 기존 Pages Router에서 App Router로 프로젝트를 마이그레이션하는 전략과 모범 사례를 살펴보겠습니다.
App Router의 주요 이점
- 서버 컴포넌트: 기본적으로 모든 컴포넌트는 서버 컴포넌트로 작동하며, 클라이언트로 전송되는 JavaScript를 줄일 수 있습니다.
- 중첩 라우팅: 레이아웃, 로딩 상태, 오류 처리 등을 중첩된 방식으로 처리할 수 있습니다.
- 병렬 라우트: 독립적으로 렌더링되는 여러 페이지를 동시에 표시할 수 있습니다.
- 데이터 가져오기 간소화: 컴포넌트 내에서 직접 비동기 데이터를 가져올 수 있습니다.
점진적 마이그레이션 전략
1. 프로젝트 설정 준비
기존 Pages Router 구조를 유지하면서 App Router를 병행할 수 있습니다:
/pages # 기존 Pages Router
/app # 새로운 App Router
2. 공통 컴포넌트 준비하기
서버/클라이언트 컴포넌트 구분을 확실히 하세요:
// components/Button.tsx
'use client'; // 클라이언트 컴포넌트 표시
export default function Button({ children }) {
return (
<button onClick={() => console.log('clicked')}>
{children}
</button>
);
}
3. 라우트 마이그레이션 시작하기
간단한 페이지부터 마이그레이션을 시작하세요:
// pages/about.js (기존)
export default function About() {
return <h1>About Us</h1>;
}
// app/about/page.tsx (새로운 방식)
export default function About() {
return <h1>About Us</h1>;
}
주요 변경 사항 적용하기
1. 데이터 가져오기 방식 변경
// pages/posts/[id].js (기존)
export async function getServerSideProps({ params }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`);
const post = await res.json();
return { props: { post } };
}
export default function Post({ post }) {
return <h1>{post.title}</h1>;
}
// app/posts/[id]/page.tsx (새로운 방식)
async function getPost(id) {
const res = await fetch(`https://api.example.com/posts/${id}`);
return res.json();
}
export default async function Post({ params }) {
const post = await getPost(params.id);
return <h1>{post.title}</h1>;
}
2. 레이아웃 구현하기
// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ko">
<body>
<header>
<nav>{/* 네비게이션 */}</nav>
</header>
<main>{children}</main>
<footer>{/* 푸터 내용 */}</footer>
</body>
</html>
);
}
3. 메타데이터 처리
// app/posts/[id]/page.tsx
import type { Metadata } from 'next';
export async function generateMetadata(
{ params }: { params: { id: string } }
): Promise<Metadata> {
const post = await getPost(params.id);
return {
title: post.title,
description: post.excerpt,
};
}