2025년에 Next.js 15·16으로 업그레이드하면서 App Router 설정을 찾는 이유는 app/ 구조와 서버 컴포넌트 기본값, 캐시 정책이 기존 pages/ 방식과 다르기 때문이에요. 시작할 때는 app/layout.tsx와 app/page.tsx를 먼저 만들고, 브라우저 API가 필요한 곳만 'use client'로 분리한 뒤, fetch 캐시와 generateMetadata까지 함께 설계하면 돼요.
App Router는 `app/` 디렉터리로 라우트를 구성하는 Next.js의 기본 권장 방식이에요.
AI로 생성된 이미지입니다Next.js 15·16 기준으로 App Router는 pages/ 대신 app/ 디렉터리를 중심으로 페이지를 구성하는 방식이에요. 2025년에도 이 구조가 기본 권장 방식으로 안내되고 있고, 최근 검색량이 늘어난 배경도 Next.js 15·16 업그레이드와 마이그레이션 수요 증가 때문이에요.[390][399]
핵심 파일은 layout.tsx, page.tsx, loading.tsx, error.tsx, not-found.tsx예요. 예를 들어 1개의 라우트 세그먼트 안에서 공통 UI는 layout.tsx, 실제 화면은 page.tsx, 로딩 상태는 loading.tsx로 나눠요. 이 조합이 App Router의 기본 작동 방식이에요.[391]
또한 App Router에서는 React Server Components가 기본값이에요. 그래서 window, useState, useEffect 같은 브라우저 중심 기능이 필요한 컴포넌트만 'use client'를 붙여 분리해야 해요. 이 경계를 초기에 명확히 잡는 것이 Next.js 15에서 특히 중요해졌어요.[392][394][401]
설정 방법은 폴더 구조를 먼저 만들고 서버·클라이언트 경계와 캐시 정책을 정하는 순서예요.
AI로 생성된 이미지입니다실전에서는 설치 명령보다 구조 설정이 더 중요해요. 제공된 2025년 기준 자료에서도 핵심은 app/ 생성, layout.tsx와 page.tsx 배치, 필요 시 'use client' 추가, 그리고 데이터 패칭과 캐싱 정책을 먼저 정하는 것이라고 정리돼 있어요.[400][401]
프로젝트 루트에
app/디렉터리를 만들어요. Next.js 15·16에서는 새 프로젝트를 App Router 기준으로 시작하는 수요가 늘었어요.[399]전역 레이아웃 파일
app/layout.tsx를 만들고,children을 감싸는 HTML 구조를 넣어요. 공통 헤더나 메타데이터 배치도 여기서 시작해요.[391][395]첫 화면용
app/page.tsx를 만들어요. 이 파일이/경로를 담당해요.[391]브라우저 이벤트, 상태 훅, DOM 접근이 필요한 컴포넌트만 별도 파일로 분리하고 파일 첫 줄에
'use client'를 넣어요. 서버 컴포넌트 기본 구조를 유지하는 데 도움이 돼요.[394]필요하면
app/blog/[slug]/page.tsx처럼 동적 라우트를 추가해요. catch-all은[...slug], optional catch-all은[[...slug]]를 사용해요.[396]API가 필요하면
app/api/posts/route.ts처럼 route handler를 만들어요. 이는pages/api를 대체하는 방향으로 쓰여요.[397]페이지별 SEO는
generateMetadata로 설정해요. 제목, 설명, Open Graph 메타데이터를 서버에서 생성할 수 있어요.[398]마지막으로
fetch캐시와 리밸리데이션 정책을 정해요. Next.js 16에서는 데이터 신선도 관리가 설정의 핵심으로 더 강조돼요.[393]
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko">
<body>{children}</body>
</html>
)
}
// app/page.tsx
export default async function HomePage() {
const res = await fetch('https://example.com/api/posts', {
next: { revalidate: 60 },
})
const posts = await res.json()
return <main>{posts.length}개의 글</main>
}
// app/blog/[slug]/page.tsx
export async function generateMetadata(
{ params }: { params: Promise<{ slug: string }> }
) {
const { slug } = await params
return {
title: `${slug} | 블로그`,
description: `${slug} 상세 페이지`,
}
}
export default async function BlogDetailPage(
{ params }: { params: Promise<{ slug: string }> }
) {
const { slug } = await params
return <article>{slug}</article>
}
// app/api/posts/route.ts
export async function GET() {
return Response.json([{ id: 1, title: 'hello' }])
}비교할 때는 Pages Router와 App Router의 파일 구조와 데이터 처리 기준이 가장 달라요.
검색자가 가장 헷갈리는 부분은 기존 pages/ 방식과 새 app/ 방식의 차이예요. 제공된 자료 기준으로는 App Router가 파일 조합, 서버 컴포넌트 기본값, route handler, 동적 세그먼트, 캐시 전략 측면에서 분명히 구분돼요.[391][394][396][397][393]
| 항목 | App Router | 비교 포인트 |
|---|---|---|
| 기본 폴더 | app/ | Next.js 15·16에서 권장 구조예요.[390] |
| 페이지 구성 | layout.tsx + page.tsx + 보조 파일 | 로딩, 에러, 404를 파일 단위로 나눠요.[391] |
| 컴포넌트 기본값 | 서버 컴포넌트 | 브라우저 기능이 필요할 때만 'use client'를 써요.[394] |
| 동적 라우트 | [slug], [...slug], [[...slug]] | 세그먼트 단위로 구조가 더 명확해요.[396] |
| API 엔드포인트 | app/api/.../route.ts | pages/api를 대체하는 방향이에요.[397] |
| SEO 설정 | generateMetadata | 제목, 설명, OG를 서버에서 생성해요.[398] |
| 데이터 신선도 | fetch 캐시·리밸리데이션 중심 | Next.js 16에서 이해가 더 중요해졌어요.[393] |
새 프로젝트라면 2025년 기준으로 App Router를 바로 적용하는 편이 자연스러워요. 반대로 기존 프로젝트를 다루는 경우에는 어느 경로를 app/ 기준으로 다시 설계할지 먼저 정리하는 것이 현실적이에요. 다만 이 판단은 팀 구조와 릴리스 일정 같은 실무 조건에 따라 달라질 수 있어요.[399]
초기 설정에서 자주 나는 오류는 서버 컴포넌트 규칙과 파일 배치 규칙을 섞어 쓰는 경우예요.
가장 흔한 실수는 모든 컴포넌트를 클라이언트 컴포넌트처럼 작성하는 일이에요. App Router에서는 서버 컴포넌트가 기본이므로, 브라우저 API가 꼭 필요한 파일에만 'use client'를 붙여야 해요. 그렇지 않으면 서버 우선 렌더링의 장점이 줄어들 수 있어요.[394]
두 번째 실수는 layout.tsx와 page.tsx 역할을 섞는 일이에요. 공통 UI를 개별 페이지마다 반복해서 넣으면 nested layout의 장점을 살리기 어려워요. App Router는 전역 레이아웃과 하위 레이아웃으로 공통 헤더, 사이드바, 메타데이터를 분리할 수 있도록 설계돼 있어요.[391][395]
세 번째 실수는 동적 라우트 문법을 혼동하는 일이에요. 단일 세그먼트는 [slug], 여러 세그먼트는 [...slug], 선택적 다중 세그먼트는 [[...slug]]예요. 파일명 1글자 차이로 라우팅 결과가 달라지기 때문에 폴더 구조를 먼저 적어보는 편이 좋아요.[396]
네 번째 실수는 Next.js 15 흐름에서 request-aware API를 동기처럼 다루는 일이에요. 제공된 자료에 따르면 params, searchParams, cookies(), headers()는 비동기 중심 흐름으로 이동하고 있어요. 그래서 예제 코드도 params: Promise<...>와 await params 형태로 맞춰 두는 것이 안전해요.[392]
마지막 실수는 캐시를 기본값에만 맡기는 일이에요. Next.js 16에서는 fetch 캐시 동작과 리밸리데이션 전략이 설정의 핵심이라고 정리돼 있어요. 예를 들어 60초마다 갱신할지, 요청마다 새 데이터를 볼지 같은 기준을 페이지 단위로 정해야 해요.[393]
설정을 안정적으로 끝내려면 라우트 구조, SEO, 데이터 신선도를 한 번에 점검하는 것이 좋아요.
AI로 생성된 이미지입니다첫 번째 팁은 라우트 트리를 종이에 먼저 적는 거예요. 예를 들어 /, /blog, /blog/[slug], /api/posts처럼 4개만 먼저 정리해도 layout.tsx, page.tsx, route.ts 배치를 실수할 가능성을 줄일 수 있어요.[391][397]
두 번째 팁은 SEO 파일링을 초기에 같이 넣는 거예요. App Router에서는 generateMetadata로 각 페이지의 제목과 설명을 서버에서 생성할 수 있어요. 블로그 상세 페이지처럼 slug가 있는 화면은 생성 시점에 메타데이터를 함께 맞추는 편이 관리가 쉬워요.[398]
세 번째 팁은 공통 UI를 레이아웃으로 끌어올리는 거예요. Next.js의 nested layout을 쓰면 1개의 전역 헤더와 1개의 섹션 사이드바를 여러 페이지에서 재사용할 수 있어요. 이 방식은 경로가 3개 이상으로 늘어날 때 유지보수 부담을 낮추는 데 도움이 돼요.[395]
네 번째 팁은 데이터 신선도 규칙을 명시하는 거예요. 예를 들어 뉴스 목록은 revalidate: 60, 관리자 화면은 더 짧은 주기, 변경이 드문 소개 페이지는 긴 주기로 설계하는 식이에요. Next.js 16에서는 이 판단이 성능과 최신성 균형의 핵심으로 다뤄져요.[393]
FAQ
Next.js App Router는 꼭 `app/` 폴더를 써야 하나요?
네. App Router는 app/ 디렉터리를 사용하는 라우팅 방식이에요. 2025년 기준 Next.js 15·16에서 권장 구조로 안내돼요.[390]
`page.tsx`와 `layout.tsx` 차이는 무엇인가요?
page.tsx는 실제 경로의 화면을 담당하고, layout.tsx는 여러 페이지가 공유하는 공통 구조를 담당해요. App Router는 이 파일들을 조합해 라우트를 구성해요.[391]
언제 `'use client'`를 붙여야 하나요?
브라우저 API, 이벤트 처리, 상태 훅처럼 클라이언트 실행이 필요한 컴포넌트에만 붙이면 돼요. App Router의 기본은 서버 컴포넌트예요.[394]
App Router에서 API는 어떻게 만들나요?
app/api/.../route.ts 파일을 만들면 돼요. 이는 App Router의 route handler 방식으로, 기존 pages/api를 대체하는 방향이에요.[397]
Next.js 15·16에서 설정할 때 가장 중요한 한 가지는 무엇인가요?
폴더만 만드는 것보다 데이터 패칭과 캐시 정책을 먼저 정하는 것이 중요해요. Next.js 16에서는 fetch 캐시와 리밸리데이션이 설정의 핵심으로 강조돼요.[393][400]