Skip to content

useApiFetch

A composable that wraps Nuxt's standard useFetch function, specifically configured for API requests. It's designed to work with API endpoints that return responses in the format { data: T }, automatically extracting the data property and handling typing.

NOTE

useApiFetch uses the same types and logic as Nuxt 3's useFetch composable. For more information about the underlying functionality, refer to the Nuxt 3 useFetch documentation.

Usage

ts
import { useApiFetch } from '#imports'

// Basic usage
const { data, pending, error } = useApiFetch('/api/users')

// With options
const { data: user } = useApiFetch('/api/users/1', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
})

// Dynamic URL with watch options
const userId = ref(1)
const { data: user } = useApiFetch(() => `/api/users/${userId.value}`, {
  watch: [userId]
})

// With payload
const { data: newUser } = useApiFetch('/api/users', {
  method: 'POST',
  body: {
    name: 'John',
    email: 'john@example.com'
  }
})

Type Signature

ts
function useApiFetch<T>(
  url: string | (() => string),
  options?: UseFetchOptions<T>
): AsyncData<T, Error>

Parameters

ParameterTypeDescription
urlstring | (() => string)URL to fetch or a function that returns the URL
optionsUseFetchOptions<T>Standard Nuxt useFetch options

Return Value

Returns Nuxt's standard AsyncData object with the following properties:

PropertyTypeDescription
dataRef<T | null>The response data, automatically extracted from { data: T }
pendingRef<boolean>Whether the request is in progress
errorRef<Error | null>Error object if the request failed
refresh() => Promise<void>Method to refresh the data
execute() => Promise<void>Method to execute the request (for non-immediate requests)

Default Behavior

  • Automatically transforms responses by extracting the data property from { data: T } structures
  • Sets requests to lazy: true by default
  • Uses the application's configured $fetch instance to maintain authentication and other global request settings

Examples

Basic Data Fetching

vue
<script setup>
import { useApiFetch } from '#imports'

// Fetch data when component is mounted (lazy by default)
const { data: posts, pending, refresh } = useApiFetch('/api/posts')
</script>

<template>
  <div>
    <button @click="refresh">Refresh Data</button>
    <p v-if="pending">Loading...</p>
    <div v-else>
      <div v-for="post in posts" :key="post.id">
        {{ post.title }}
      </div>
    </div>
  </div>
</template>

Conditional Fetching

ts
const searchQuery = ref('')
const { data: searchResults, execute } = useApiFetch(() => `/api/search?q=${searchQuery.value}`, {
  immediate: false // Don't fetch automatically
})

// Trigger the request manually when needed
function performSearch() {
  if (searchQuery.value.length >= 3) {
    execute()
  }
}

POST Request with Error Handling

ts
const formData = reactive({
  title: '',
  content: ''
})

const { data, error, execute } = useApiFetch('/api/posts', {
  method: 'POST',
  body: formData,
  immediate: false
})

async function submitForm() {
  await execute()
  if (!error.value) {
    // Handle successful submission
  }
}

Source Code