createError, error.value, showError
Fetch Error Handling
Catch errors from useFetch via error.value, raise structured errors from server routes with createError, and trigger the global error page with showError.
What you'll learn
- Read error.value from a useFetch destructure
- Throw createError with statusCode and statusMessage on the server
- Use showError to navigate to error.vue
Network failures and 4xx/5xx responses are part of life. Nuxt gives you three tools for handling them cleanly.
Reading error.value
<script setup lang="ts">
const { data, error } = await useFetch('/api/posts')
</script>
<template>
<div v-if="error" class="error">
Could not load: {{ error.statusMessage ?? error.message }}
</div>
<ul v-else>
<li v-for="p in data" :key="p.id">{{ p.title }}</li>
</ul>
</template> error.value is null on success and holds an error object on failure. It contains statusCode,
statusMessage, and any data you returned from the server.
Throwing on the Server
In server routes, do not return ad-hoc shapes for errors — throw with createError:
// server/api/users/[id].ts
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
const user = await db.user.find(id)
if (!user) {
throw createError({
statusCode: 404,
statusMessage: 'User not found'
})
}
return user
}) The thrown error becomes a proper HTTP response with the right status, and the client receives a structured error.
showError for Full-Page Errors
When a failure should take over the whole page (e.g. unauthorized access to a protected route),
call showError:
const { data, error } = await useFetch('/api/secret')
if (error.value) {
showError({ statusCode: 401, statusMessage: 'Please log in' })
} This renders your error.vue page with the supplied props. Use clearError({ redirect: '/' })
from the error page to recover.