title: fetch
description: 확장된 fetch 함수에 대한 API 참조 문서입니다.
url: "https://nextjs.org/docs/app/api-reference/functions/fetch"
version: 16.1.6
lastUpdated: 2026-02-27
prerequisites:
안녕하세요! 프론트엔드 개발자로서 한 단계 더 도약하기 위해 Next.js를 공부하고 계시는군요. 공식 문서가 영어라 조금 막막하셨을 텐데, 제가 아주 쉽고 친절하게, 그리고 실무적인 팁까지 팍팍 넣어서 설명해 드릴게요.
Next.js는 서버의 각 요청이 자체적인 영구 캐싱(persistent caching) 및 재검증(revalidation) 방식을 설정할 수 있도록 웹 fetch() API를 확장했어요.
우리가 흔히 브라우저에서 사용할 때 cache 옵션은 fetch 요청이 브라우저의 HTTP 캐시와 어떻게 상호작용할지를 나타내잖아요? 그런데 Next.js의 이 확장 기능을 사용하면, cache 옵션은 서버 사이드의 fetch 요청이 프레임워크의 영구적인 데이터 캐시(Data Cache)와 어떻게 상호작용할지를 결정하게 됩니다.
가장 멋진 점은 서버 컴포넌트(Server Components) 내부에서 async와 await를 사용해서 fetch를 직접 호출할 수 있다는 거예요.
export default async function Page() {
let data = await fetch('[https://api.vercel.app/blog](https://api.vercel.app/blog)')
let posts = await data.json()
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
export default async function Page() {
let data = await fetch('[https://api.vercel.app/blog](https://api.vercel.app/blog)')
let posts = await data.json()
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
💡 강사의 팁: > 예전 React.js 환경에서는 비동기 데이터를 가져올 때
useEffect를 쓰고useState로 상태 관리를 하느라 코드가 꽤 길어졌었죠. 하지만 Next.js 서버 컴포넌트에서는 위 예시처럼await fetch()한 줄로 깔끔하게 끝납니다.
참고로 요즘 프론트엔드 생태계에서는 TypeScript가 거의 필수 표준이잖아요? 제공된 두 가지 예시 중에서도 가급적 첫 번째.tsx예시처럼 타입스크립트를 활용해서 개발하는 습관을 들이시는 걸 강력히 추천합니다!
fetch(url, options)Next.js는 기본 웹 fetch() API를 확장한 것이기 때문에, 기존에 사용 가능한 네이티브 옵션들을 전혀 무리 없이 그대로 사용할 수 있어요.
options.cache이 옵션은 요청이 Next.js의 데이터 캐시와 어떻게 상호작용해야 하는지를 설정합니다.
fetch(`https://...`, { cache: 'force-cache' | 'no-store' })
auto no cache (기본값): 개발(development) 환경에서는 Next.js가 매 요청마다 원격 서버에서 리소스를 가져와요. 하지만 next build를 할 때는 라우트가 정적으로 사전 렌더링(statically prerendered) 되기 때문에 딱 한 번만 가져옵니다. 만약 라우트에서 동적 API (Dynamic APIs)가 감지되면, Next.js는 매 요청마다 리소스를 새롭게 가져옵니다.no-store: 라우트에서 동적 API가 감지되지 않더라도, Next.js가 매 요청마다 원격 서버에서 리소스를 무조건 새로 가져옵니다. (캐시를 전혀 쓰지 않겠다는 뜻이죠!)force-cache: Next.js가 데이터 캐시(Data Cache)에서 일치하는 요청이 있는지 찾아봅니다.💡 강사의 팁: > 이 캐싱 옵션은 실전 프로젝트를 설계할 때 핵심 중의 핵심이에요.
예를 들어 다른 플랫폼의 블로그 글들을 모아서 보여주는 'Velog 뷰어' 같은 포트폴리오를 만드신다면, 글 목록이 1초마다 실시간으로 바뀔 필요는 없잖아요? 이럴 땐force-cache나 정해진 주기마다 업데이트하는 방식을 써서 렌더링 속도를 높이고 불필요한 API 호출을 막는 게 좋습니다.
반면에, 사용자가 입력한 텍스트를 즉각 번역해 주는 'AI 문서 번역기' 같은 서비스라면 어떨까요? 사용자가 요청할 때마다 무조건 새로운 번역 결과값을 받아와야 하니, 이럴 땐 반드시no-store를 사용해서 캐싱을 꺼주어야 합니다. 기획하는 서비스의 성격에 맞춰 옵션을 고르는 센스를 발휘해 보세요!
options.next.revalidatefetch(`https://...`, { next: { revalidate: false | 0 | number } })
리소스의 캐시 수명을 초(seconds) 단위로 설정합니다. 데이터 캐시와 연관이 깊죠.
false - 리소스를 무기한으로 캐시합니다. 의미상으로는 revalidate: Infinity와 완전히 똑같아요. (단, HTTP 캐시는 시간이 지남에 따라 오래된 리소스를 자체적으로 삭제할 수도 있습니다.)0 - 리소스가 캐시되는 것을 아예 방지합니다. (cache: 'no-store'와 비슷한 효과를 냅니다.)number - (초 단위) 리소스의 캐시 수명이 최대 n초가 되도록 지정합니다. 일정 시간이 지나면 백그라운드에서 데이터를 새로고침하는 ISR(Incremental Static Regeneration) 패턴에 주로 쓰여요.알아두면 좋은 점 (Good to know):
- 만약 개별
fetch()요청이 라우트의 기본revalidate값보다 더 낮은 숫자로revalidate를 설정하면, 전체 라우트의 재검증 주기도 그 낮은 숫자로 줄어듭니다. (가장 짧은 주기를 따라가게 돼요.)- 만약 같은 라우트 내에서 동일한 URL을 가진 두 개의 fetch 요청이 서로 다른
revalidate값을 가지고 있다면, 더 낮은 값이 사용됩니다.{ revalidate: 3600, cache: 'no-store' }처럼 서로 충돌하는 옵션은 허용되지 않아요. 이 경우 두 옵션 모두 무시되며, 개발 모드에서는 터미널에 경고(warning) 메시지가 출력됩니다.
options.next.tagsfetch(`https://...`, { next: { tags: ['collection'] } })
리소스에 캐시 태그(cache tags)를 설정합니다. 이렇게 태그를 달아두면 나중에 revalidateTag 함수를 사용해서 원할 때(on-demand) 데이터를 콕 집어 재검증할 수 있어요. 커스텀 태그의 최대 길이는 256자이고, 한 번에 달 수 있는 태그 항목의 최대 개수는 128개입니다.
💡 강사의 팁: > 시간 기반으로 업데이트(
revalidate: number)하는 것도 좋지만, 실무에서는 "새 글이 작성되었을 때"나 "데이터가 수정되었을 때"처럼 특정 액션이 일어났을 때만 화면을 갱신해야 할 때가 많아요. 이럴 때 바로 이tags옵션이 빛을 발합니다.
auto no store 및 cache: 'no-store'가 최신 데이터를 보여주지 않을 때Next.js는 빠른 응답성을 제공하고 비용이 청구되는 API 호출을 줄이기 위해 로컬 개발 환경의 HMR(Hot Module Replacement - 코드를 수정하면 새로고침 없이 화면이 바뀌는 기능) 과정에서 서버 컴포넌트의 fetch 응답을 캐시해 둡니다.
기본적으로 이 HMR 캐시는 기본값인 auto no cache와 cache: 'no-store' 옵션을 가진 요청을 포함한 모든 fetch 요청에 적용돼요. 이게 무슨 말이냐면, 분명히 캐시를 하지 않겠다고 설정한 요청이더라도 단순히 코드를 수정해서 일어나는 HMR 새로고침 사이에서는 최신 데이터가 보이지 않을 수 있다는 뜻입니다. 하지만 페이지를 이동(navigation)하거나 브라우저 전체 새로고침(full-page reloads)을 하면 캐시는 깔끔하게 지워집니다.
더 자세한 정보는 serverComponentsHmrCache 문서를 참고해 주세요.
개발 모드에서 만약 요청에 cache-control: no-cache 헤더가 포함되어 있다면, 방금까지 열심히 배운 options.cache, options.next.revalidate, 그리고 options.next.tags 옵션들이 모두 무시됩니다. 그리고 fetch 요청은 원본 소스에서 바로 최신 데이터를 가져오게 처리되죠.
일반적으로 브라우저는 개발자 도구(developer tools)에서 캐시를 비활성화해 두었거나, 사용자가 강력 새로고침(hard refresh, 예: Ctrl+Shift+R 또는 Cmd+Shift+R)을 할 때 이 cache-control: no-cache 헤더를 포함해서 보냅니다.
| 버전 (Version) | 변경 사항 (Changes) |
|---|---|
v13.0.0 | fetch 기능이 처음 도입되었습니다. |
모든 문서의 의미론적 개요를 보시려면 https://nextjs.org/docs/sitemap.md를 참고해 주세요.
사용 가능한 모든 문서의 색인(index)을 보시려면 https://nextjs.org/docs/llms.txt를 참고해 주세요.