Next.js App Router 시작하기 – React 개발자를 위한 입문 가이드

Next.js App Router 시작하기 – React 개발자를 위한 입문 가이드

React로 개발하다 보면 한 번쯤 Next.js를 고민하게 됩니다. SEO가 필요하거나, 초기 로딩 속도를 개선하고 싶거나, 풀스택으로 확장하고 싶을 때 Next.js는 자연스러운 선택입니다.

Next.js 13부터 도입된 App Router는 기존 Pages Router와 완전히 다른 방식입니다. React 개발자라면 익숙한 개념도 있지만, 새로 배워야 할 것도 있습니다. 이 글에서 핵심만 빠르게 정리해드립니다.

App Router vs Pages Router

Next.js에는 두 가지 라우팅 시스템이 있습니다.

구분 Pages Router App Router
도입 시점 Next.js 초기 Next.js 13+
폴더 pages/ app/
기본 컴포넌트 Client Component Server Component
레이아웃 _app.js, _document.js layout.js (중첩 가능)
데이터 페칭 getServerSideProps async 컴포넌트에서 직접 fetch

2024년 이후 새 프로젝트라면 App Router를 권장합니다. Pages Router도 계속 지원되지만, 새로운 기능은 App Router에 집중되고 있습니다.

프로젝트 생성

npx create-next-app@latest my-app

설치 중 몇 가지 질문이 나옵니다:

Would you like to use App Router? › Yes
Would you like to use TypeScript? › Yes (권장)
Would you like to use Tailwind CSS? › 선택

App Router를 선택하면 app/ 폴더가 생성됩니다.

파일 기반 라우팅 이해하기

App Router의 핵심은 폴더 구조가 곧 URL이라는 점입니다.

app/
├── page.js          → /
├── about/
│   └── page.js      → /about
├── blog/
│   ├── page.js      → /blog
│   └── [slug]/
│       └── page.js  → /blog/hello-world (동적 라우트)

특수 파일들

파일 역할
page.js 해당 경로의 페이지 UI
layout.js 공통 레이아웃 (헤더, 푸터 등)
loading.js 로딩 중 표시할 UI
error.js 에러 발생 시 표시할 UI
not-found.js 404 페이지

첫 번째 페이지 만들기

app/page.js를 열어보세요:

export default function Home() {
  return (
    <main>
      <h1>Hello, Next.js!</h1>
      <p>App Router로 만든 첫 페이지입니다.</p>
    </main>
  );
}

npm run dev로 실행하면 http://localhost:3000에서 확인할 수 있습니다.

Server Component vs Client Component

이 부분이 React 개발자가 가장 헷갈리는 포인트입니다.

App Router에서 모든 컴포넌트는 기본적으로 Server Component입니다.

Server Component (기본값)

// app/posts/page.js
// 이건 서버에서 실행됩니다

async function getPosts() {
  const res = await fetch('https://api.example.com/posts');
  return res.json();
}

export default async function PostsPage() {
  const posts = await getPosts();  // 서버에서 직접 fetch

  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Server Component의 장점:
– 번들 크기에 포함되지 않음
– 데이터베이스에 직접 접근 가능
– API 키 같은 민감한 정보를 안전하게 사용

Client Component

useState, useEffect, 이벤트 핸들러 등 브라우저 기능이 필요하면 Client Component로 만들어야 합니다.

'use client';  // 이 한 줄이 핵심!

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      클릭: {count}
    </button>
  );
}

'use client'는 파일 최상단에 선언해야 합니다. 이 파일과 여기서 import하는 모든 모듈이 클라이언트 번들에 포함됩니다.

언제 무엇을 쓸까?

상황 선택
데이터 fetch만 하고 표시 Server Component
useState, useEffect 필요 Client Component
onClick 등 이벤트 핸들러 Client Component
브라우저 API 사용 (localStorage 등) Client Component

: Server Component 안에 Client Component를 넣을 수 있습니다. 반대는 불가능합니다.

Layout으로 공통 UI 만들기

layout.js는 여러 페이지에서 공유하는 UI를 정의합니다.

// app/layout.js (루트 레이아웃)
export default function RootLayout({ children }) {
  return (
    <html lang="ko">
      <body>
        <header>
          <nav>사이트 네비게이션</nav>
        </header>
        <main>{children}</main>
        <footer>© 2026</footer>
      </body>
    </html>
  );
}

페이지를 이동해도 레이아웃은 다시 렌더링되지 않습니다. 상태도 유지됩니다.

중첩 레이아웃

app/
├── layout.js         → 전체 레이아웃
├── blog/
│   ├── layout.js     → 블로그 전용 레이아웃
│   └── page.js

/blog 페이지는 두 레이아웃이 모두 적용됩니다.

정리

개념 핵심 포인트
App Router app/ 폴더 사용, Next.js 13+ 권장 방식
파일 라우팅 폴더 구조 = URL, page.js가 실제 페이지
Server Component 기본값, 서버에서 렌더링, fetch 직접 가능
Client Component 'use client' 선언, useState/이벤트 필요 시
Layout layout.js로 공통 UI, 중첩 가능

React 개발자라면 App Router의 기본 개념은 금방 익힐 수 있습니다. 처음에는 Server/Client Component 구분이 어색할 수 있지만, 몇 번 써보면 자연스러워집니다.

위로 스크롤