Next 14 App Router로 대시보드를 만들고 있는데요, 서버 컴포넌트에서 API를 호출해서 그리는 페이지가 자꾸 옛날 데이터를 보여줍니다. 관리자가 값을 바꿔도 이 페이지엔 반영이 안 되고, 심지어 재배포를 해야 그때 값으로 한 번 갱신되고 또 고정돼요.
캐시 문제 같아서 fetch에 옵션을 줬습니다.
const res = await fetch(`${API}/stats`, { cache: 'no-store' })이렇게 no-store를 넣었는데도 여전히 옛날 값이에요. 로컬 dev에선 잘 바뀌는데 배포(build) 후에만 이럽니다. 뭔가 캐시 레이어가 여러 개 있는 것 같은데 감이 안 잡히네요.
댓글 3
그래서 이 라우트를 동적 렌더로 강제해야 해요. 해당 page.tsx 맨 위에 export const dynamic = 'force-dynamic'을 넣으세요. 그럼 매 요청마다 서버에서 새로 렌더합니다. 값이 자주 안 바뀌면 force-dynamic 대신 export const revalidate = 60처럼 초 단위 재검증(ISR)을 걸어도 되고요. 관리자 액션 직후 즉시 반영이 필요하면 그 액션에서 revalidatePath로 콕 집어 무효화하는 방법도 있습니다.
하나 더 확인할 게 있는데, 혹시 이 stats 호출을 fetch가 아니라 axios 같은 라이브러리로 하고 계신 건 아니죠? Next의 캐시/no-store는 자기네 확장된 fetch에만 걸리는 거라, axios로 부르면 no-store고 뭐고 Next가 관여를 안 해요. 그래서 라우트 정적 판정이랑 겹치면 지금 증상이 딱 나옵니다.
axios를 유지하실 거면 데이터 캐시는 포기하고 라우트 레벨로만 제어하세요. 즉 page에 force-dynamic(또는 revalidate)을 걸면 매 요청마다 서버 렌더가 돌면서 axios 호출도 그때그때 새로 나갑니다. 이 조합이면 axios 코드는 안 건드려도 됩니다. 관리자 변경 즉시 반영까지 원하면 그 변경 처리하는 곳에서 revalidatePath로 이 경로를 무효화해주면 되고요. 데이터 캐시의 세밀한 재검증(태그 기반 revalidate 같은)까지 쓰고 싶어질 때 그때 fetch로 옮기는 걸 검토하시면 됩니다.