개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Next.js SSR — 요청마다 서버에서 HTML을 생성하는 방법

2025년 5월 25일
Next.jsSSRServer Side RenderingDynamic Rendering캐시 없음

페이지를 열 때마다 서버가 그 순간의 데이터를 담아 HTML을 만들어 보내준다. Next.js App Router에서는 fetch에 cache: 'no-store'를 지정하는 것만으로 이 동작을 활성화할 수 있다. 캐시된 스냅샷이 아닌 살아있는 데이터가 필요할 때 SSR은 가장 직접적인 해답이다.

SSR이란

SSR(Server Side Rendering)은 클라이언트의 요청이 도착할 때마다 서버에서 HTML을 새로 생성해 응답하는 렌더링 방식이다. Next.js App Router에서는 이를 Dynamic Rendering이라고도 부른다.

브라우저          Next.js 서버          데이터 소스
  │                   │                    │
  │── GET /page ──>   │                    │
  │                   │── fetch(url) ──>   │
  │                   │<── 최신 데이터 ──  │
  │                   │  (HTML 생성)       │
  │<── 완성된 HTML ── │                    │
  │  (hydration)      │                    │

빌드 타임이 아닌 런타임에 HTML이 만들어지므로, 응답마다 다른 내용을 담을 수 있다.

cache: no-store로 SSR 활성화

App Router에서 SSR을 적용하는 가장 간단한 방법은 fetch 옵션에 cache: 'no-store'를 전달하는 것이다.

// app/dashboard/page.tsx
export default async function DashboardPage() {
  const res = await fetch('https://api.example.com/stats', {
    cache: 'no-store', // 요청마다 새로 fetch
  });
  const data = await res.json();

  return <StatsView data={data} />;
}

cache: 'no-store' — HTTP Cache-Control의 no-store와 동일한 의미. Next.js는 이 옵션을 보고 해당 페이지를 Dynamic으로 전환한다.

cookies, headers, searchParams 같은 Dynamic API를 사용해도 페이지가 자동으로 Dynamic Rendering으로 전환된다.

import { cookies } from 'next/headers';

export default async function ProfilePage() {
  const cookieStore = cookies(); // 이것만으로도 SSR 전환
  const token = cookieStore.get('auth_token')?.value;

  const res = await fetch('https://api.example.com/me', {
    headers: { Authorization: `Bearer ${token}` },
  });
  const user = await res.json();

  return <Profile user={user} />;
}

언제 SSR을 선택하는가

  • 로그인한 사용자마다 다른 데이터를 보여줘야 할 때
  • 실시간성이 중요한 대시보드, 피드, 재고 현황
  • 요청 헤더나 쿠키 값에 따라 응답이 달라져야 할 때
  • SEO가 필요하지만 데이터가 빌드 시점에 확정되지 않을 때

CSR / SSG / ISR / SSR 비교

방식HTML 생성 시점데이터 신선도SEO서버 부하
CSR브라우저 (런타임)요청마다취약낮음
SSG빌드 타임빌드 시점 고정우수없음
ISR빌드 + 주기적 재생성설정한 주기우수낮음
SSR서버 (런타임)항상 최신우수높음

장단점

장점

  • 요청마다 최신 데이터를 HTML에 포함해 응답하므로 데이터 신선도가 가장 높다.
  • 초기 HTML이 완성된 상태로 전달되어 SEO와 초기 렌더링 속도가 모두 좋다.
  • 사용자별 개인화 콘텐츠를 서버에서 안전하게 처리할 수 있다.

단점

  • 요청마다 서버 연산이 발생하므로 트래픽이 많을수록 인프라 비용이 증가한다.
  • 서버 응답 시간(TTFB)이 SSG보다 길어질 수 있다.
  • CDN 엣지 캐싱의 이점을 온전히 누리기 어렵다.

데이터 변경 주기가 길거나 사용자 구분이 필요 없다면 SSG나 ISR이 더 효율적이다. SSR은 "항상 최신, 항상 개인화"가 요구될 때 꺼내는 카드다.

← 이전 글Next.js SSG — 빌드 시 HTML을 미리 생성하는 방법
다음 글 →Next.js ISR — 정적 페이지를 주기적으로 재생성하는 방법