Skip to content

useFetch Configuration ​

Generated useFetch composables accept native Nuxt useFetch options plus the extra runtime options documented below.

Runtime-specific options ​

ts
interface ApiRequestOptions<T> {
  onRequest?: (context: RequestContext) =>
    | void
    | Promise<void>
    | ModifiedRequestContext
    | Promise<ModifiedRequestContext>

  onSuccess?: (data: T) => void | Promise<void>
  onError?: (error: any) => void | Promise<void>
  onFinish?: (context: FinishContext<any>) => void | Promise<void>

  skipGlobalCallbacks?: boolean | Array<'onRequest' | 'onSuccess' | 'onError' | 'onFinish'>

  pick?: readonly string[]
  transform?: (data: T) => any

  paginated?: boolean
  initialPage?: number
  initialPerPage?: number
  paginationConfig?: PaginationConfig

  baseURL?: string
  method?: string
  body?: any
  headers?: Record<string, string> | HeadersInit
  query?: Record<string, any>
  params?: Record<string, any>
}

Nuxt options still apply

Native options such as server, lazy, immediate, watch, default, dedupe, onResponse, and onResponseError remain available because the generated wrapper extends useFetch.

Nuxt useFetch Documentation

onRequest ​

Use onRequest to modify the outgoing request. Return only the fields you want to override.

ts
useFetchGetPets({}, {
  onRequest: ({ headers, query }) => ({
    headers: {
      ...headers,
      Authorization: `Bearer ${token.value}`,
    },
    query: {
      ...query,
      locale: 'en',
    },
  }),
})

The request context shape is:

ts
interface RequestContext {
  url: string
  method: string
  body?: any
  headers?: Record<string, string>
  query?: Record<string, any>
}

onSuccess, onError, onFinish ​

These callbacks run after the runtime has applied pick and transform.

ts
useFetchCreatePet(
  { body: { name: 'Fluffy' } },
  {
    immediate: false,
    onSuccess: (pet) => {
      console.log('Created', pet.id)
    },
    onError: (error) => {
      console.error(error)
    },
    onFinish: ({ success }) => {
      console.log('Completed', success)
    },
  }
)

onFinish receives:

ts
interface FinishContext<T> {
  data?: T
  error?: any
  success: boolean
}

Global callbacks ​

Global callback rules come from a Nuxt plugin that provides getGlobalApiCallbacks.

ts
// plugins/api-callbacks.ts
export default defineNuxtPlugin(() => {
  return {
    provide: {
      getGlobalApiCallbacks: () => [
        {
          onRequest: ({ headers }) => ({
            headers: {
              ...headers,
              Authorization: `Bearer ${useCookie('auth-token').value}`,
            },
          }),
        },
        {
          methods: ['DELETE'],
          onSuccess: () => {
            console.log('Delete succeeded')
          },
        },
      ],
    },
  }
})

Per request, you can disable all global callbacks or selected stages:

ts
useFetchGetPublicPets({}, {
  skipGlobalCallbacks: true,
})

useFetchGetPets({}, {
  skipGlobalCallbacks: ['onRequest', 'onError'],
})

Global headers ​

Global headers are resolved in this order:

  1. useApiHeaders() if you define that composable in your app
  2. nuxtApp.$getApiHeaders() if useApiHeaders() is not available
  3. Request-specific headers passed to the composable
ts
// composables/useApiHeaders.ts
export const useApiHeaders = () => {
  const token = useCookie('auth-token')

  return {
    ...(token.value ? { Authorization: `Bearer ${token.value}` } : {}),
  }
}

Pagination options ​

Pagination is shared with useAsyncData and is driven by paginationConfig.

ts
const { data, pagination, nextPage } = useFetchGetPets({}, {
  paginated: true,
  initialPage: 2,
  initialPerPage: 50,
})

If you need one request to follow a different backend pagination convention, override it inline:

ts
useFetchGetPets({}, {
  paginated: true,
  paginationConfig: {
    meta: {
      metaSource: 'body',
      fields: {
        total: 'meta.total',
        totalPages: 'meta.last_page',
        currentPage: 'meta.current_page',
        perPage: 'meta.per_page',
        dataKey: 'data',
      },
    },
    request: {
      sendAs: 'query',
      params: { page: 'page', perPage: 'per_page' },
      defaults: { page: 1, perPage: 15 },
    },
  },
})

baseURL ​

If you do not pass baseURL, the runtime tries runtimeConfig.public.apiBaseUrl.

ts
useFetchGetPets({}, {
  baseURL: 'https://api.example.com',
})

Next steps ​

Released under the Apache-2.0 License.