오늘 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 로그의 안내 문구도 사라지고
- 코드만 봐도 의도가 명확해졌다
'React' 카테고리의 다른 글
| Vite(로컬)와 Nginx Proxy의 차이(feat. 401, CORS) (0) | 2026.02.12 |
|---|---|
| Next.js 경로 끝 슬래시(/) (feat. 308 redirect) (0) | 2025.05.30 |
| 전체 페이지가 새로고침 되는 이유 e.preventDefault() (0) | 2025.05.27 |
| [Next.js] 무료 에디터 Tiptap커스텀하기 (0) | 2025.03.26 |
| [TypeScript] 제네릭을 활용한 setDto 최적화 - any 대신 T를 쓰는 이유 (0) | 2025.03.13 |