Nuxt의 $fetchuseFetch 완벽 가이드 - 언제, 왜, 어떻게 써야 할까?

Nuxt 3에서는 API 호출 방법으로 **$fetch**와 useFetch 두 가지가 자주 사용됩니다. 이 둘은 모두 HTTP 요청을 보낼 수 있지만, 용도·사용법·실행 타이밍에서 중요한 차이가 있습니다. Nuxt 생태계에서 이 함수를 언제 어떤 상황에 써야 할지 고민된다면, 이 글이 명확한 기준이 되어 드릴 것입니다.


$fetch란?

$fetch는 Nuxt가 제공하는 단순하고 강력한 HTTP 클라이언트 함수입니다. 기본 fetch()와 비슷하지만, 자동으로 JSON 파싱, 에러 처리가 내장되어 있어 더욱 편리하게 사용할 수 있습니다.

주요 특징

  • 브라우저와 서버 모두에서 사용 가능
  • 비반응형: 단순한 Promise 기반 데이터 반환
  • Nuxt 3에서 전역으로 바로 사용(await $fetch(...))
  • fetch보다 간편한 문법

예시 코드

const data = await $fetch('/api/posts')

useFetch란?

useFetch는 Nuxt의 컴포지션 API 기반 비동기 데이터 패칭 함수로, Reactivity(반응성)와 SSR, Suspense까지 고려한 데이터 패칭을 지원합니다.

주요 특징

  • SSR 프리패치와 캐싱 지원
  • 반응형(ref) 데이터 반환: data.value, pending.value, error.value
  • Vue 템플릿에서도 바로 사용 가능
  • watch와 결합해 쿼리 파라미터 등 동적 대응에 적합

예시 코드

const { data, pending, error } = await useFetch('/api/posts')

두 함수 핵심 비교

항목$fetchuseFetch
반환값Promise<any>{ data, pending, error } (ref 상태)
반응성❌ 없음✅ 있음 (템플릿에서도 반응형)
SSR 지원❌ 기본 fetch와 동일✅ 서버에서 미리 실행, Suspense 최적화
사용 위치어디서나(함수, setup 등)setup() 컴포지션 API 등에서 사용
추천 용도단순 동기 요청, 유틸 함수 호출페이지 데이터 패칭, SSR, 비동기 뷰 렌더링

실제 코드 예시로 이해하기

useFetch를 템플릿에서 활용

<script setup>
const { data, pending, error } = await useFetch('/api/posts')
</script>

<template>
  <div v-if="pending">로딩중...</div>
  <div v-else-if="error">에러 발생!</div>
  <ul>
    <li v-for="post in data" :key="post.id">{{ post.title }}</li>
  </ul>
</template>

$fetch를 함수로 활용

<script setup>
async function createPost(post) {
  const result = await $fetch('/api/posts', {
    method: 'POST',
    body: post,
  })
  console.log('업로드 결과:', result)
}
</script>

언제 뭘 써야 할까? 상황별 추천

상황추천 함수
단순 값만 받아오고 싶을 때$fetch
페이지 진입 시 자동으로 데이터 패칭이 필요할 때useFetch
pending, error 상태까지 템플릿에서 활용하고 싶을 때useFetch
함수 내부에서만 호출하고, 반응성이 필요 없을 때$fetch

useFetch만 써도 충분한 상황

  • API로부터 데이터를 받아 페이지나 컴포넌트에 렌더링할 때
  • 초기 데이터 로딩 및 로딩/에러 상태 핸들링이 필요할 때
  • SSR 프리렌더링 기능을 활용하고 싶을 때
  • 반응형(ref) 데이터가 필요한 경우
const { data, pending, error } = await useFetch('/api/posts')

$fetch가 더 적합한 상황

상황이유
내부 로직에서만 쓰고, 반응형 필요 없음useFetchref 구조가 불필요함
직접 POST/PUT/DELETE 요청이 필요할 때useFetch는 기본적으로 GET 요청 위주
API 결과를 직접 캐싱·통제하고 싶을 때$fetch가 더 직관적
await $fetch('/api/posts', {
  method: 'POST',
  body: { title: 'New post' },
})

마무리 및 인사이트

정리하자면, **일반적인 Nuxt 프로젝트에서는 SSR, 반응성, Suspense 등 Nuxt 특화 기능이 모두 들어있는 useFetch가 "기본 선택지"**로 충분합니다. 단, 단순한 유틸성 API 호출이나 POST/PUT/DELETE 등 특수 요청, 반응형 구조가 필요 없는 경우에는 $fetch가 더 편리합니다.

Nuxt의 데이터 패칭에는 이외에도 useAsyncData, useLazyFetch 같은 패턴이 존재합니다. 프로젝트 규모가 커지거나, 데이터 패칭 전략이 복잡해질 경우 이들 함수의 차이점도 익혀 두면 좋습니다.

이번 글에서는 Nuxt의 핵심 데이터 패칭 함수인 $fetchuseFetch의 활용법, 그리고 언제 어떤 상황에 각 함수를 선택해야 하는지 살펴보았습니다. 실제 프로젝트에서 두 함수를 적절히 조합하면, 더욱 효율적이고 견고한 Nuxt 앱 개발이 가능해집니다.