현재 오즈코딩스쿨 강의를 통해 프론트엔드를 학습하고 있습니다.
본 포스트는 해당 강의에 대한 내용 정리를 목적으로 합니다.

Next.js는 React 기반의 웹 프레임워크이다. 서버 사이드 렌더링, 정적 사이트 생성, 라우팅, API 구축 등 다양한 기능을 제공하는 것이 특징이다.





next 12버전 npx create-next-app@12
next 13버전 npx create-next-app@13
SSR은 페이지 요청 시 서버에서 HTML을 생성하여 브라우저에 전달하는 방식이다.

사용자가 페이지를 요청하면 서버가 React 컴포넌트를 렌더링하고, 완성된 HTML을 브라우저에 전달한다.
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return { props: { data } };
}
서버는 기본 HTML만 전달하고, 이후 자바스크립트가 로딩되면 브라우저가 렌더링을 수행한다.
Next.js에서는 기본 React처럼 CSR도 지원하며, useEffect, fetch 등을 통해 클라이언트에서 데이터를 가져올 수 있다.

Next.js는 이 3가지 방식을 페이지별로 선택적으로 적용 가능하다는 것이 큰 장점이다.

| 구분 | 실행 시점 | 장점 | 단점 | 대표 예시 |
|---|---|---|---|---|
| SSR | 매 요청마다 | 최신 데이터, SEO 강함 | 느릴 수 있음 | 대시보드, 실시간 정보 |
| SSG | 빌드 시 | 빠름, 캐시 가능 | 데이터 갱신 어려움 | 블로그, 문서 |
| ISR | 첫 요청 + 갱신 주기 | 빠름 + 최신성 보완 | 일정 시간 동안 오래된 데이터 가능 | 쇼핑몰, 뉴스 |
Next.js의 프리렌더링 방식이란, React 컴포넌트를 미리 HTML로 변환해두는 것을 말한다. 이렇게 하면 페이지가 더 빨리 뜨고 SEO도 좋아진다.
빌드 시 HTML을 미리 만들어 저장해두는 방식이다.
기본 SSG: getStaticProps() 사용
동적 라우트용 SSG: getStaticPaths() + getStaticProps()
ISR (증분 정적 재생성): getStaticProps() 안에 revalidate 포함
export async function getStaticProps() {
const data = await fetch(...).then(res => res.json());
return {
props: { data }, // 빌드 시 데이터 포함
revalidate: 60 // (선택) ISR: 60초마다 새로 빌드
};
}
각 요청 시 HTML을 서버에서 생성하는 방식이다.
getServerSideProps()를 사용한다.export async function getServerSideProps() {
const data = await fetch(...).then(res => res.json());
return {
props: { data } // 요청마다 새로운 데이터
};
}
| 방식 | 실행 시점 | 함수 | 장점 | 단점 |
|---|---|---|---|---|
| Static Generation | 빌드 시 | getStaticProps() | 빠름, 캐시 가능 | 데이터 변경 반영 어려움 |
| ISR | 빌드 + 주기적 | getStaticProps() + revalidate | 빠름 + 최신성 유지 | 재생성 타이밍 제어 필요 |
| SSR | 요청 시 | getServerSideProps() | 항상 최신 데이터 제공 가능 | 속도 느릴 수 있음 |
| 버전 | 라우팅 방식 | 설명 |
|---|---|---|
| 12 이하 | pages 디렉토리 기반 | 파일 이름이 곧 라우트 (pages/index.js → /) |
| 13 | app 디렉토리 도입 (App Router) | 폴더 구조로 라우팅, 중첩 레이아웃/서버 컴포넌트 지원 |
| 14 | App Router 안정화 | 13의 App Router가 기본 권장 구조로 자리잡음 |
app/
└─ dashboard/
├─ page.tsx → /dashboard
├─ layout.tsx → 하위 경로 공통 레이아웃
| 버전 | 방식 | 특징 |
|---|---|---|
| 12 | getStaticProps, getServerSideProps, getInitialProps | 모두 pages 폴더 전용 함수 |
| 13 | fetch() + async 서버 컴포넌트에서 직접 사용 | app 폴더 내 서버 컴포넌트 자체가 fetch 가능 |
| 14 | cache, revalidateTag 등 지원 확장 | 세분화된 캐싱 제어 가능 (Full Route Cache 등) |
// app/posts/page.tsx
async function Page() {
const res = await fetch('https://api.example.com/posts', { cache: 'no-store' });
const data = await res.json();
return <PostList data={data} />;
}
| 버전 | 방식 | 설명 |
|---|---|---|
| 12 | pages/api/* → API Routes | Next.js 내 REST API 구현 가능 |
| 13 | app/api/*/route.js → New API Routes | GET, POST 핸들러 함수 기반 구조 |
| 14 | app/api/* 방식 개선 | RSC 기반 API, Edge 기능 활용 가능 |
// app/api/hello/route.ts
export async function GET() {
return Response.json({ message: "Hello from API!" });
}
| 버전 | 방식 | 설명 |
|---|---|---|
| 12 | _app.js, _document.js 사용 | 모든 페이지에 공통 레이아웃 지정 |
| 13 | layout.tsx 사용 (중첩 가능) | 폴더별로 독립적 레이아웃 구조 사용 가능 |
| 14 | layout.tsx 방식 유지 + 안정화 | 중첩 레이아웃, Slot 방식 등 공식 지원 |
// app/dashboard/layout.tsx
export default function DashboardLayout({ children }) {
return (
<div>
<Sidebar />
<main>{children}</main>
</div>
);
}
| 항목 | 12버전 | 13버전 | 14버전 |
|---|---|---|---|
| 라우팅 | pages 디렉토리 | app 디렉토리 도입 | app 디렉토리 기본화 |
| 데이터 패칭 | getStaticProps 등 | fetch() 직접 사용 | fetch + 캐시 세분화 |
| API 작성 | pages/api/* | app/api/route.ts | Edge 지원 등 확장 |
| 레이아웃 | _app.js 중심 | layout.tsx 중첩 가능 | 구조 강화/정착 |