Skip to main content

Overview

The FetchHooks interface provides lifecycle hooks that allow you to intercept and handle different stages of the fetch request process.

Type Signature

export interface FetchHooks<T = any, R extends ResponseType = ResponseType> {
  onRequest?: MaybeArray<FetchHook<FetchContext<T, R>>>;
  onRequestError?: MaybeArray<FetchHook<FetchContext<T, R> & { error: Error }>>;
  onResponse?: MaybeArray<
    FetchHook<FetchContext<T, R> & { response: FetchResponse<T> }>
  >;
  onResponseError?: MaybeArray<
    FetchHook<FetchContext<T, R> & { response: FetchResponse<T> }>
  >;
}

type FetchHook<C extends FetchContext = FetchContext> = (
  context: C
) => MaybePromise<void>;

type MaybePromise<T> = T | Promise<T>;
type MaybeArray<T> = T | T[];

Hooks

onRequest

onRequest
FetchHook<FetchContext<T, R>> | FetchHook<FetchContext<T, R>>[]
Called before the request is sent. Use this to modify request options, add headers, or log requests.
Context Parameters:
context.request
FetchRequest
The request URL or Request object
context.options
ResolvedFetchOptions<R>
Resolved request options that will be used for the fetch
context.response
FetchResponse<T> | undefined
Undefined at this stage
context.error
Error | undefined
Undefined at this stage
Example:
await ofetch('/api/users', {
  onRequest({ request, options }) {
    console.log('Fetching:', request)
    options.headers.set('X-Custom-Header', 'value')
  }
})

onRequestError

onRequestError
FetchHook<FetchContext<T, R> & { error: Error }> | FetchHook<FetchContext<T, R> & { error: Error }>[]
Called when the request fails to execute (network error, timeout, etc.). Does not include HTTP error responses (4xx, 5xx) - use onResponseError for those.
Context Parameters:
context.request
FetchRequest
The request URL or Request object
context.options
ResolvedFetchOptions<R>
Request options used for the fetch
context.error
Error
required
The error that occurred during the request
context.response
FetchResponse<T> | undefined
Undefined for network errors
Example:
await ofetch('/api/users', {
  onRequestError({ request, error }) {
    console.error('Request failed:', request, error)
    // Log to error tracking service
    errorTracker.log(error)
  }
})

onResponse

onResponse
FetchHook<FetchContext<T, R> & { response: FetchResponse<T> }> | FetchHook<FetchContext<T, R> & { response: FetchResponse<T> }>[]
Called after a successful response is received (any status code). Use this to log responses, modify response data, or handle specific status codes.
Context Parameters:
context.request
FetchRequest
The request URL or Request object
context.options
ResolvedFetchOptions<R>
Request options used for the fetch
context.response
FetchResponse<T>
required
The fetch response object with parsed data in _data property. See FetchResponse.
context.error
Error | undefined
Undefined for successful responses
Example:
await ofetch('/api/users', {
  onResponse({ response }) {
    console.log('Response status:', response.status)
    console.log('Response data:', response._data)
    
    // Modify response data
    if (response._data) {
      response._data.timestamp = Date.now()
    }
  }
})

onResponseError

onResponseError
FetchHook<FetchContext<T, R> & { response: FetchResponse<T> }> | FetchHook<FetchContext<T, R> & { response: FetchResponse<T> }>[]
Called when the response has an HTTP error status (4xx or 5xx). Use this to handle specific error cases before the error is thrown.
Context Parameters:
context.request
FetchRequest
The request URL or Request object
context.options
ResolvedFetchOptions<R>
Request options used for the fetch
context.response
FetchResponse<T>
required
The fetch response object with error status. See FetchResponse.
context.error
Error | undefined
May contain the error that will be thrown
Example:
await ofetch('/api/users', {
  onResponseError({ request, response }) {
    console.error(
      `Error ${response.status}: ${request}`
    )
    
    // Handle specific status codes
    if (response.status === 401) {
      // Redirect to login
      window.location.href = '/login'
    }
  }
})

Multiple Hooks

You can provide multiple hooks as an array. They will be called in order:
await ofetch('/api/users', {
  onRequest: [
    ({ options }) => {
      options.headers.set('X-Request-ID', generateId())
    },
    ({ request }) => {
      console.log('Request:', request)
    }
  ],
  onResponse: [
    ({ response }) => {
      console.log('Status:', response.status)
    },
    ({ response }) => {
      logAnalytics(response)
    }
  ]
})

Async Hooks

Hooks can be asynchronous:
await ofetch('/api/users', {
  async onRequest({ options }) {
    const token = await getAuthToken()
    options.headers.set('Authorization', `Bearer ${token}`)
  },
  async onResponse({ response }) {
    await saveToCache(response._data)
  }
})

Global Hooks

Set hooks globally when creating a fetch instance:
const apiFetch = ofetch.create({
  onRequest({ options }) {
    options.headers.set('X-Client-Version', '1.0.0')
  },
  onResponseError({ response }) {
    if (response.status === 401) {
      redirectToLogin()
    }
  }
})

Type Parameters

T
any
default:"any"
The expected type of the response data
R
ResponseType
default:"ResponseType"
The response type. See ResponseType.

Build docs developers (and LLMs) love