개발#Next.js
Next.js App Router 마이그레이션 가이드
·10분 읽기
App Router란?#
Next.js 13에서 도입된 App Router는 React Server Components를 기반으로 한 새로운 라우팅 시스템입니다. 기존 pages/ 디렉토리 방식(Pages Router)을 대체하며, app/ 디렉토리를 사용합니다.
주요 변경사항#
| 구분 | Pages Router | App Router |
|---|---|---|
| 라우팅 | pages/ 디렉토리 | app/ 디렉토리 |
| 데이터 페칭 | getServerSideProps, getStaticProps | async 서버 컴포넌트 |
| 레이아웃 | _app.tsx | layout.tsx (중첩 가능) |
| 기본 컴포넌트 | 클라이언트 컴포넌트 | 서버 컴포넌트 |
서버 컴포넌트 vs 클라이언트 컴포넌트#
App Router의 가장 큰 변화는 기본적으로 모든 컴포넌트가 서버 컴포넌트라는 점입니다.
서버 컴포넌트 (기본값)#
// app/posts/page.tsx
// 'use client' 없이 사용 — 서버에서만 실행됨
async function PostsPage() {
// 서버에서 직접 DB 조회 가능
const posts = await db.posts.findMany()
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
export default PostsPage
클라이언트 컴포넌트#
'use client'
// useState, useEffect 등 훅 사용 시 필요
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
클릭 수: {count}
</button>
)
}
export default Counter
데이터 페칭 마이그레이션#
Before: Pages Router#
// pages/blog/[slug].tsx
import type { GetStaticProps, GetStaticPaths } from 'next'
export const getStaticPaths: GetStaticPaths = async () => {
const posts = await getAllPosts()
return {
paths: posts.map(post => ({ params: { slug: post.slug } })),
fallback: false,
}
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const post = await getPostBySlug(params?.slug as string)
return { props: { post } }
}
export default function BlogPost({ post }: { post: Post }) {
return <article>{post.content}</article>
}
After: App Router#
// app/blog/[slug]/page.tsx
import { getAllPosts, getPostBySlug } from '@/lib/mdx'
import { notFound } from 'next/navigation'
export async function generateStaticParams() {
const posts = getAllPosts()
return posts.map(post => ({ slug: post.slug }))
}
export default async function BlogPost({
params,
}: {
params: { slug: string }
}) {
const post = getPostBySlug(params.slug)
if (!post) notFound()
return <article>{post.content}</article>
}
마이그레이션 순서 권장사항#
- 점진적 마이그레이션:
pages/와app/은 공존 가능 - 레이아웃부터 시작:
app/layout.tsx먼저 구성 - 정적 페이지 먼저: 데이터 페칭이 없는 페이지부터
- 클라이언트 컴포넌트 최소화: 필요한 경우에만
'use client'사용 - 테스트 보강: 마이그레이션 후 동작 검증
알려진 함정들#
- 서버 컴포넌트에서 훅 사용 불가:
useState,useEffect등은 클라이언트 컴포넌트에서만 사용 - Context는 클라이언트 전용:
createContext와useContext는 클라이언트 컴포넌트에서만 동작 next/headers는 서버 전용:cookies(),headers()등은 서버 컴포넌트에서만 사용 가능
관련 포스트
개발#성능 최적화#Web Vitals#Next.js#프론트엔드
웹 성능 최적화 실전 가이드: Core Web Vitals와 최적화 기법
LCP, FID, CLS 등 Core Web Vitals의 의미와 실제 프론트엔드 성능을 개선하는 실전 기법을 정리했습니다.
·9분 읽기
개발#Docker#DevOps#컨테이너#인프라
Docker 입문 가이드: 개발자가 꼭 알아야 할 컨테이너 기초
Docker가 왜 필요한지부터 이미지, 컨테이너, Docker Compose까지 개발자 관점에서 실용적으로 정리했습니다.
·8분 읽기
개발#API#REST#GraphQL#백엔드
REST API vs GraphQL: 실무에서 뭘 선택해야 할까?
REST와 GraphQL의 핵심 차이를 이해하고, 프로젝트 상황에 따른 올바른 선택 기준을 정리했습니다.
·8분 읽기