Кастомный useFetch в Nuxt

Как создать собственный fetch-клиент для вызова внешнего API в Nuxt.

В Nuxt часто делают фронтенд и ходят во внешнее API — удобно задать опции по умолчанию для всех запросов к нему.

Утилита $fetch (её использует useFetch) намеренно не настраивается глобально: так поведение запросов в приложении остаётся предсказуемым, а модули и интеграции могут опираться на ядро.

При этом Nuxt позволяет создать свой fetch-клиент под ваш API (или несколько, если API несколько).

Рецепт: API-клиент с авторизацией

Допустим, внешнее API на https://api.nuxt.com требует JWT через nuxt-auth-utils, а при ответе 401 нужно перенаправлять на /login.

app/composables/useAPI.ts
export const useAPI = createUseFetch({
  baseURL: 'https://api.nuxt.com',
  onRequest ({ options }) {
    const { session } = useUserSession()
    if (session.value?.token) {
      options.headers.set('Authorization', `Bearer ${session.value.token}`)
    }
  },
  async onResponseError ({ response }) {
    if (response.status === 401) {
      await navigateTo('/login')
    }
  },
})

Теперь каждый вызов useAPI добавляет заголовок авторизации и обрабатывает 401:

app/pages/dashboard.vue
<script setup lang="ts">
const { data: profile } = await useAPI('/me')
const { data: orders } = await useAPI('/orders')
</script>
Узнать больше Docs > 4 X > API > Composables > Create Use Fetch.

Рецепт: свой экземпляр $fetch

Если нужен более низкоуровневый контроль, создайте экземпляр $fetch в плагине Nuxt и используйте его с useAsyncData или передайте в createUseFetch.

$fetch — настроенный экземпляр ofetch: можно задать базовый URL сервера Nuxt и вызывать функции напрямую при SSR (без лишнего HTTP).
app/plugins/api.ts
export default defineNuxtPlugin((nuxtApp) => {
  const { session } = useUserSession()

  const api = $fetch.create({
    baseURL: 'https://api.nuxt.com',
    onRequest ({ request, options, error }) {
      if (session.value?.token) {
        options.headers.set('Authorization', `Bearer ${session.value?.token}`)
      }
    },
    async onResponseError ({ response }) {
      if (response.status === 401) {
        await nuxtApp.runWithContext(() => navigateTo('/login'))
      }
    },
  })

  return {
    provide: {
      api,
    },
  }
})

Дальше можно вызывать свой $fetch напрямую:

app/app.vue
<script setup>
const { $api } = useNuxtApp()
const { data: modules } = await useAsyncData('modules', () => $api('/modules'))
</script>
Обёртка в useAsyncDataизбегает двойной загрузки данных при SSR (сервер и клиент при гидрации).
Прочитайте и отредактируйте живой пример в Docs > 4 X > Examples > Advanced > Use Custom Fetch Composable.