--- name: data-fetching description: useFetch, useAsyncData, and $fetch for SSR-friendly data fetching --- # Data Fetching Nuxt provides composables for SSR-friendly data fetching that prevent double-fetching and handle hydration. ## Overview - `$fetch` - Basic fetch utility (use for client-side events) - `useFetch` - SSR-safe wrapper around $fetch (use for component data) - `useAsyncData` - SSR-safe wrapper for any async function ## useFetch Primary composable for fetching data in components: ```vue ``` ### With Options ```ts const { data } = await useFetch('/api/posts', { // Query parameters query: { page: 1, limit: 10 }, // Request body (for POST/PUT) body: { title: 'New Post' }, // HTTP method method: 'POST', // Only pick specific fields pick: ['id', 'title'], // Transform response transform: (posts) => posts.map(p => ({ ...p, slug: slugify(p.title) })), // Custom key for caching key: 'posts-list', // Don't fetch on server server: false, // Don't block navigation lazy: true, // Don't fetch immediately immediate: false, // Default value default: () => [], }) ``` ### Reactive Parameters ```vue ``` ### Computed URL ```vue ``` ## useAsyncData For wrapping any async function: ```vue ``` ### Multiple Requests ```vue ``` ## $fetch For client-side events (form submissions, button clicks): ```vue ``` **Important**: Don't use `$fetch` alone in setup for initial data - it will fetch twice (server + client). Use `useFetch` or `useAsyncData` instead. ## Return Values All composables return: | Property | Type | Description | |----------|------|-------------| | `data` | `Ref` | Fetched data | | `error` | `Ref` | Error if request failed | | `status` | `Ref<'idle' \| 'pending' \| 'success' \| 'error'>` | Request status | | `refresh` | `() => Promise` | Refetch data | | `execute` | `() => Promise` | Alias for refresh | | `clear` | `() => void` | Reset data and error | ## Lazy Fetching Don't block navigation: ```vue ``` ## Refresh & Watch ```vue ``` ## Caching Data is cached by key. Share data across components: ```vue ``` Refresh cached data globally: ```ts // Refresh specific key await refreshNuxtData('current-user') // Refresh all data await refreshNuxtData() // Clear cached data clearNuxtData('current-user') ``` ## Interceptors ```ts const { data } = await useFetch('/api/auth', { onRequest({ options }) { options.headers.set('Authorization', `Bearer ${token}`) }, onRequestError({ error }) { console.error('Request failed:', error) }, onResponse({ response }) { // Process response }, onResponseError({ response }) { if (response.status === 401) { navigateTo('/login') } }, }) ``` ## Passing Headers (SSR) `useFetch` automatically proxies cookies/headers from client to server. For `$fetch`: ```vue ```