$fetch

As a modern web application framework, Nuxt.js provides developers with a powerful and streamlined HTTP client known as $fetch. Built on top of the robust ofetch library, $fetch serves as the standard mechanism for handling data fetching in Nuxt applications, offering a significantly smoother experience than native browser APIs or traditional third-party libraries like axios.
Compared to conventional fetching methods, $fetch stands out due to several built-in optimizations tailored for modern development workflows:

  • Automatic Serialization and Parsing: It seamlessly handles JSON payloads. When sending data, it serializes objects automatically; when receiving data, it parses the response body without requiring manual calls like response.json().
  • Intelligent Error Handling: Any response outside the successful 2xx range automatically triggers an exception, making it easy to catch errors using standard try...catch blocks.
  • Seamless SSR Integration: During server-side rendering, $fetch intelligently resolves relative URLs into absolute ones using request context, eliminating common cross-origin or path resolution issues.
  • Robust Type Safety: When paired with TypeScript, it provides excellent type inference out of the box, mapping your API responses directly to your data structures.

Basic Usage

Within a Nuxt component, you can utilize $fetch directly inside your <script setup> block. Here is a straightforward example of fetching a list of users upon component mount:

<script setup>
const users = ref([])

onMounted(async () => {
  try {
    users.value = await $fetch('/api/users')
  } catch (error) {
    console.error('Failed to fetch users:', error)
  }
})
</script>

In this scenario, /api/users acts as a relative path. On the client side, the browser resolves it against the current origin, whereas on the server side, Nuxt constructs the absolute URL automatically using incoming request headers.

Advanced Configuration Options

To accommodate complex business requirements, $fetch accepts an optional configuration object as its second argument.

Custom Headers and Query Parameters

You can easily pass query strings and modify request headers using the params and headers properties:

const data = await $fetch('/api/products', {
  params: {
    page: 1,
    limit: 10,
    category: 'electronics'
  },
  headers: {
    'Authorization': 'Bearer your-token-here'
  }
})

Sending POST Requests

For operations that modify data, such as creating or updating resources, specify the HTTP method and payload body:

const newUser = { name: 'Alice', email: 'alice@example.com' }

const result = await $fetch('/api/users', {
  method: 'POST',
  body: newUser
})

console.log('Successfully created:', result)

When passing a JavaScript object to the body option, $fetch automatically converts it into a JSON string and sets the appropriate Content-Type: application/json header.

Error Handling Mechanism

The error handling workflow is intuitive and developer-friendly. Non-2xx HTTP responses cause the underlying promise to reject immediately. Catching these errors grants you access to comprehensive diagnostic properties:

try {
  await $fetch('/api/non-existent-resource')
} catch (error) {
  console.log(`Request failed with status: ${error.status}`)
  console.log('Server error response:', error.data)
}

This design removes the boilerplate code typically required to manually check response flags like response.ok.

Comparing $fetch and useFetch

While $fetch is extremely versatile, Nuxt also offers useFetch as a higher-level composable specifically designed for component-level state management.

  • $fetch is a pure utility function returning a Promise. You are responsible for manually tracking loading and error states.
  • useFetch wraps $fetch under the hood, exposing reactive references for data, pending, and error, alongside built-in features like request deduplication and caching.

Best Practices for Selection:

  • Use $fetch when working outside of Vue components (such as in Nitro server routes) or when you need granular control over the request lifecycle.
  • Use useFetch inside Vue components when you want to leverage automatic reactivity, caching, and streamlined state management.

Conclusion

The $fetch utility is a cornerstone of the Nuxt.js ecosystem. By abstracting away the tedious boilerplate of HTTP communication, it empowers developers to concentrate fully on core business logic. Whether you are building small features or enterprise-grade applications, mastering $fetch will significantly elevate your productivity and code maintainability.