#Show nuxt 404 page on server side network request
15 messages · Page 1 of 1 (latest)
Hi @mellow magnet. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
To show a Nuxt 404 page when a server-side request returns a 404 status, you have several options. Here's how you can handle this scenario:
Option 1: Using createError
The most straightforward approach is to throw an error with createError when your API request returns a 404:
<script setup>
const route = useRoute()
const { data } = await useAsyncData('pageData', () => {
return fetch(`/api/your-endpoint/${route.params.id}`)
.then(res => {
if (!res.ok) {
if (res.status === 404) {
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found',
fatal: true // Important for static generation
})
}
throw new Error('API Error')
}
return res.json()
})
})
// If no data was returned but no error was thrown
if (!data.value) {
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found'
})
}
</script>
The createError utility will trigger Nuxt's error handling system, which will display your custom error page defined in error.vue at the root of your project. The fatal: true parameter is especially important if you're using static site generation to ensure the error page is displayed properly.
Option 2: Using setResponseStatus
If you want more control over the response status without necessarily showing the error page, you can use setResponseStatus:
<script setup>
const event = useRequestEvent()
const { data, error } = await useAsyncData('pageData', () => {
return fetch('/api/your-endpoint')
.then(res => {
if (res.status === 404) {
if (event) {
setResponseStatus(event, 404, 'Page Not Found')
}
return null
}
return res.json()
})
})
if (!data.value) {
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found'
})
}
</script>
[setResponseStatus documentation](<https://nuxt.com/docs/api/utils/set-response-status>)
## Option 3: Handling in API call with try/catch
Another approach is to use a try/catch block with server-side detection:
```typescript
<script setup>
const userService = useUserService();
const { data, error } = await useAsyncData('data', () => {
return userService.getSelf().catch(() => {
if (import.meta.server) {
const response = requestEvent.node.res;
if (!response.headersSent) {
response.writeHead(302, {Location: '/login'});
response.end();
} else {
router.push('/login');
}
}
})
});
</script>
This example from a Stack Overflow solution shows how to handle authentication errors, but the same pattern works for 404 errors by changing the status code to 404 and redirecting to your error page.
Make sure you have an error.vue file in your project root to customize the error page that will be displayed. This file should use the useError() composable to access the error details:
<script setup>
const error = useError();
</script>
<template>
<div>
<h1>{{ error.value.statusCode }}</h1>
<p>{{ error.value.message }}</p>
<NuxtLink to="/">Back to home</NuxtLink>
</div>
</template>
Remember that if you're using a hosting provider like Hostinger, you might need to configure their 404 handling to allow your Nuxt error page to be displayed instead of their default error page.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@mellow magnet Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@hollow ledge Tried to do:
const { data } = await useAsyncData(key.value, async () => {
try {
// some logic here
return getData();
} catch (error) {
if (error && typeof error === 'object' && 'statusCode' in error && error.statusCode === 404) {
throw createError({
statusCode: 404,
message: 'Data not found,
});
}
throw createError({
statusCode: 500,
});
}
});
But it just crash the page
Let me check the knowledge base for you again. One moment! :books:
I see the issue with your code. When using useAsyncData with error handling, there are a few important details to consider to properly show the 404 page instead of crashing the application.
Here's how to fix your implementation:
const { data } = await useAsyncData(key.value, async () => {
try {
// some logic here
return await getData();
} catch (error) {
if (error && typeof error === 'object' && 'statusCode' in error && error.statusCode === 404) {
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found',
fatal: true // This is important for proper error handling
});
}
throw createError({
statusCode: 500,
statusMessage: 'Server Error',
fatal: true
});
}
});
The key changes needed are:
-
Add the
fatal: trueproperty to yourcreateErrorcall. This is crucial for ensuring the error is properly handled and the error page is displayed, especially when using static site generation. -
Use
statusMessageinstead of justmessagefor better error handling. ThestatusMessageis recommended for API routes as it propagates better to the client side. -
Make sure you're awaiting the
getData()function if it returns a promise.
According to the documentation, when you throw an error created with createError:
- On server-side, it will trigger a full-screen error page which you can clear with
clearError. - On client-side, it will throw a non-fatal error by default. That's why adding
fatal: trueis important to trigger the full-screen error page.
If you're still experiencing issues, you might want to check if your error.vue file is properly set up at the root of your project to handle these errors correctly.
Also, if you're using a hosting provider, be aware that some providers might override your custom 404 page with their own. In that case, you might need to configure your hosting settings as mentioned in a Stack Overflow solution for Hostinger users who had to modify their error pages in the hosting control panel.
Stack Overflow solution
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@mellow magnet Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@hollow ledge I added fatal: true but still no full screen error page
Let me check the knowledge base for you again. One moment! :books:
I understand you're still having issues with displaying the full-screen error page even after adding fatal: true. Let's troubleshoot this issue based on the knowledge sources.
Possible Causes and Solutions
1. Recent Nitro Version Issue
There appears to be a known issue with stack traces in recent Nitro versions (2.10.0+) that might affect error handling:
// This issue was identified in nitropack 2.10.0
const stack =
!isDev && !import.meta.prerender && (error.unhandled || error.fatal)
? []
: ((error.stack as string) || "")
You could try pinning your nitropack version to 2.9.7 in your package.json resolutions:
"resolutions": {
"nitropack": "2.9.7"
}
2. Error in Layout vs. Error Page
If you're using a custom layout with your error page, make sure your default layout uses <slot /> instead of <NuxtPage /> for the error content:
<!-- In your default.vue layout -->
<template>
<div>
<CustomHeader />
<main>
<slot /> <!-- Use slot instead of NuxtPage for error.vue -->
</main>
<CustomFooter />
</div>
</template>
3. Error Handling in Middleware
If your error is occurring in middleware, there was a recent fix to properly show fatal errors thrown in middleware. Make sure you're using the latest Nuxt version:
// In middleware
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found',
fatal: true
});
4. Check Your error.vue Implementation
Ensure your error.vue file is properly set up at the root of your project:
<script setup>
const error = useError();
</script>
<template>
<div>
<h1>{{ error.statusCode }}</h1>
<p>{{ error.message }}</p>
<button @click="clearError">Go back</button>
</div>
</template>
[useError documentation](<https://nuxt.com/docs/api/composables/use-error>)
### 5. Try Using NuxtErrorBoundary
If you're trying to handle errors in a specific component or section, consider using `<NuxtErrorBoundary>`:
```vue
<template>
<NuxtErrorBoundary>
<!-- Your content -->
<template #error="{ error }">
<p>An error occurred: {{ error }}</p>
</template>
</NuxtErrorBoundary>
</template>
NuxtErrorBoundary documentation
6. Hosting Provider Issues
If you're deploying to a hosting provider, they might be intercepting and displaying their own error pages instead of your custom ones:
For Hostinger users: Try changing the 404 page from the hosting control panel itself, and put an empty HTML page.