React

[Next.js] force-dynamic를 쓰게 된 이유

연신내고독한늑대 2025. 12. 23. 15:17

오늘 Next.js 프로젝트를 운영 서버에 올리기 전에 npm run build를 돌렸다.
빌드는 잘 되는데, 로그에 계속 눈에 걸리는 문구가 하나 있었다.

Dynamic server usage: Route /admin couldn't be rendered statically
because it used `cookies`

처음엔 “이거 오류인가?” 싶었다.
페이지가 안 뜨는 것도 아니고, 빌드가 실패하는 것도 아닌데 계속 나온다.
그래서 차분하게 원인을 정리해봤다.

 

■ Next.js는 기본적으로 정적 페이지를 만든다

Next.js(App Router)를 쓰면서 한 가지를 다시 명확히 느꼈다.

→ Next.js는 기본적으로 페이지를 정적으로 만들려고 한다.

출처: Rendering: Server Components | Next.js

 

Rendering: Server Components | Next.js

Learn how you can use React Server Components to render parts of your application on the server.

nextjs.org

즉, 아무 설정도 안 하면 Next.js는 “이 페이지 정적으로 만들어도 되지?”라고 먼저 판단한다.

■ 그럼 언제 “자동으로” 동적 페이지가 될까?

Next.js는 개발자가 굳이 설정하지 않아도, 아래와 같은 “동적 서버 기능”을 사용하면 자동으로 Dynamic Rendering으로 전환한다. 대표적인 예가 바로 이것들이다.

 

  • cookies()
  • headers()
  • searchParams
  • draftMode()
  • unstable_noStore()
import { cookies } from 'next/headers';

cookies();

 

즉, 이 한 줄만 있어도 해당 페이지는 정적 렌더링 대상에서 제외된다.

■ 왜 build 로그에 경고가 나올까?

나의 폴더 구조는 아래와 같았다.

app/
 ├─ admin/
 │   ├─ layout.tsx   ← getCurrentUser() 사용
 │   └─ page.tsx
 └─ gift/
     ├─ layout.tsx
     └─ page.tsx

그리고 layout.tsx에서 다음과 같이 인증을 처리한다.

import { cookies } from 'next/headers';

export default async function AdminLayout({ children }) {
  const user = await getCurrentUser(); // 내부에서 cookies() 사용
  return <>{children}</>;
}

이 경우:

  • /admin/** 하위 모든 페이지는
  • layout 단계에서 이미 cookies()를 사용
  • → 전부 Dynamic Rendering 대상

하지만 Next.js는 빌드 과정에서 한 번은 이렇게 시도한다. 

→ “이 페이지, 혹시 정적으로 만들 수 있지 않을까?”

그리고 실패하면 아래 로그를 남긴다.

Route /admin couldn't be rendered statically because it used `cookies`

이건 에러가 아니라 의도 확인용 안내 메시지다.

중요한 포인트는 이거다.

  • 실행에 문제 없음
  • 빌드 실패 아님
  • 실제 서비스 동작 정상

Next.js 입장에서 보면 그냥 이런 상황이다.

→ “정적으로 만들려고 했는데, cookies를 쓰네? 그럼 동적으로 처리할게.”

이 과정을 로그로 알려주고 있었을 뿐이다.

■ 로그가 안보이게 하는 방법

아래의 코드를 동적페이지로 만들어 주는 훅에다가 사용 하면 된다(나의 경우 amin/layout.tsx)

export const dynamic = 'force-dynamic';

이렇게 선언해주니:

  • build 로그의 안내 문구도 사라지고
  • 코드만 봐도 의도가 명확해졌다