Next.js 15 App Router를 활용해 SSR, SSG, Server Components의 개념과 리액트 SPA와의 차이, 실무에서의 선택 기준을 배웁니다.
🤔 Vite 리액트의 한계
지금까지 배운 Vite + React는 완전한 클라이언트 사이드 렌더링(CSR)입니다. 브라우저에서 JS를 다운받아 실행해야 화면이 보입니다. 이 방식의 한계:
- SEO 불리: 검색 엔진 봇이 빈 HTML만 보게 됩니다.
- 느린 초기 로딩: JS 다운로드 → 파싱 → 실행 → 렌더링 순서.
- 소셜 공유 미리보기 없음: Open Graph 태그가 JS 실행 후 동적으로 추가되면 Twitter/KakaoTalk 미리보기가 안 됩니다.
이 문제를 해결하는 것이 Next.js입니다. 현재 버전 15에서는 App Router를 기본으로 사용합니다.
🏗️ 렌더링 전략 3가지
| 전략 | 약자 | 언제 HTML 생성 | 적합한 페이지 |
|---|---|---|---|
| 정적 사이트 생성 | SSG | 빌드 타임 | 마케팅, 블로그, 문서 |
| 서버 사이드 렌더링 | SSR | 요청 시마다 | 개인화, 실시간 데이터 |
| 클라이언트 렌더링 | CSR | 브라우저에서 | 대시보드, 인증 후 화면 |
Next.js App Router는 컴포넌트 단위로 이 전략을 섞어 사용할 수 있습니다. 기본적으로 모든 컴포넌트는 서버 컴포넌트입니다.
🖥️ 서버 컴포넌트 vs 클라이언트 컴포넌트
// app/posts/page.tsx — 서버 컴포넌트 (기본)
// 서버에서 실행 → HTML을 클라이언트로 전달
// useState, useEffect, onClick 사용 불가
// 데이터베이스 직접 접근, 환경변수 서버 전용 값 사용 가능
async function PostsPage() {
// 서버에서 직접 DB 조회 또는 API 호출
const posts = await fetch('https://api.example.com/posts').then((r) => r.json())
return (
<main>
<h1>게시글 목록</h1>
{posts.map((post: { id: number; title: string }) => (
<div key={post.id}>{post.title}</div>
))}
</main>
)
}
// app/components/LikeButton.tsx — 클라이언트 컴포넌트
// 'use client' 선언 필수!
// useState, useEffect, 이벤트 핸들러 사용 가능
'use client'
import { useState } from 'react'
export function LikeButton({ postId, initialCount }: { postId: number; initialCount: number }) {
const [count, setCount] = useState(initialCount)
const [liked, setLiked] = useState(false)
async function handleLike() {
if (liked) return
setLiked(true)
setCount((c) => c + 1)
await fetch(`/api/posts/${postId}/like`, { method: 'POST' })
}
return (
<button onClick={handleLike} className={liked ? 'text-red-500' : 'text-gray-400'}>
❤️ {count}
</button>
)
}
핵심 패턴: 서버 컴포넌트로 데이터를 가져오고, 클라이언트 컴포넌트를 인터랙션 필요한 곳에만 배치합니다. 이렇게 하면 JS 번들 크기가 최소화되고 초기 로딩이 빨라집니다.
📁 App Router 파일 구조
app/
├── layout.tsx # 전체 레이아웃 (HTML, body 포함)
├── page.tsx # / 경로
├── loading.tsx # 로딩 중 표시 (자동 Suspense)
├── error.tsx # 에러 표시 (자동 Error Boundary)
├── not-found.tsx # 404 페이지
├── posts/
│ ├── page.tsx # /posts 경로
│ └── [id]/
│ └── page.tsx # /posts/:id 경로
파일 이름 규칙만으로 라우팅, 로딩 상태, 에러 처리가 자동으로 설정됩니다.
⚡ Next.js vs Vite + React — 언제 무엇을 선택할까
| 상황 | 선택 |
|---|---|
| SEO가 중요한 공개 사이트 | Next.js |
| 초기 로딩 속도 중요 | Next.js |
| 대시보드, 인증 후 화면만 | Vite + React (SPA) |
| 빠른 프로토타입 | Vite + React |
| 풀스택 (API + 프론트 함께) | Next.js |
✅ 정리
- Next.js App Router: 서버에서 HTML을 생성해 SEO와 초기 로딩 속도 개선.
- 서버 컴포넌트(기본): 데이터 패칭, DB 접근 / 클라이언트 컴포넌트(
'use client'): useState, 이벤트. - SEO 필요, 실시간 데이터, 풀스택이면 Next.js. 단순 SPA 대시보드면 Vite + React.
관련 주제
- SSR
- SSG
- CSR
- 서버 컴포넌트
- 클라이언트 컴포넌트
- App Router
- 렌더링 전략
- Open Graph
- 빌드 타임
- 개발·프로그래밍
- 개발·프로그래밍 강의
- 리액트 입문 — 컴포넌트로 만드는 웹
- 무료강의
- 무료 온라인 강의
- NUGUNA
- 누구나
댓글
0/1000
불러오는 중...
