Next.js는 사용하는 API를 읽어
각 라우트를 빌드 때 한 번 만들지, 요청마다 다시 만들지 별도 질문 창에서 고르지 않아. 프레임워크가 코드에서 요청별 정보에 기대는 API를 찾고 렌더링 방식을 판단해.
| API | 판단에 미치는 영향 |
|---|---|
cookies() | 요청별 동적 렌더링이 필요해. |
headers() | 요청별 동적 렌더링이 필요해. |
searchParams | URL마다 달라지는 동적 값이야. |
connection() | 동적 렌더링을 명시적으로 선택해. |
캐시하지 않는 fetch() | 동적 데이터 지점으로 취급돼. |
필요하면 의도를 강제로 검증해
export const dynamic = 'force-static'을 쓰면 동적 API가 섞였을 때 오류가 나므로 정적 계약을 지킬 수 있어. 'force-dynamic'은 현재 코드에 동적 신호가 없어도 요청마다 렌더링하도록 보장해.
선택은 운영 비용으로 이어져
정적 라우트는 CDN에서 제공할 수 있어 요청마다 서버 계산 비용이 들지 않아. 동적 라우트는 매번 앱 코드를 실행해. 개인화가 필요하지 않은 화면에 무심코 쿠키를 읽는 것만으로도 비용 모델이 바뀔 수 있으니 빌드 결과를 확인해.
next build 결과에서 각 라우트가 정적·동적으로 분류된 이유를 확인해. 예상과 다른 라우트는 cookies(), headers(), 캐시 없는 fetch가 어느 조상에서 들어왔는지 추적해. feature flag나 분석 코드 하나가 넓은 레이아웃에 놓여 전체 하위를 동적으로 바꾸는 경우가 흔해. 라우트 분류가 예상과 다르면 결과만 고치지 말고 어떤 API 호출이 동적 신호를 만들었는지 추적해. 그래야 다음 변경에서도 같은 실수를 빌드 결과로 설명할 수 있어.
force-static과 force-dynamic은 탐지기를 이기는 주문이 아니라 의도를 검증하는 계약이야. 실제 요청별 값이 필요한데 정적으로 강제하거나, 정적이어도 되는 화면을 동적으로 고정하면 오류나 비용으로 돌아와. override를 쓸 때는 자동 판단이 왜 부족한지 기록해. 정적 페이지에 쿠키, header, searchParams, 캐시 없는 fetch를 하나씩 추가하며 build 분류 변화를 기록해. 넓은 layout에 동적 API를 넣었을 때 하위 라우트가 얼마나 영향을 받는지 확인하고, override가 의도와 충돌하면 빌드에서 실패하게 만들어.