Show nuxt 404 page on server side network request

I am using useAsyncData to get the page data on the server, how i can show nuxt 404 if the request returns 404
8 Replies
kapa.ai
kapa.ai3w ago
Hi @salomon_.. 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>
<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. createError documentation 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>
<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 Option 3: Handling in API call with try/catch Another approach is to use a try/catch block with server-side detection:
<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>
<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. Stack Overflow solution 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>
<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>
useError documentation 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: ----------------------
kapa.ai
kapa.ai3w ago
<@1029431292170874910> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
salomon_.
salomon_.OP3w ago
@kapa.ai 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,
});
}
});
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
kapa.ai
kapa.ai3w ago
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
});
}
});
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: 1. Add the fatal: true property to your createError call. This is crucial for ensuring the error is properly handled and the error page is displayed, especially when using static site generation. 2. Use statusMessage instead of just message for better error handling. The statusMessage is recommended for API routes as it propagates better to the client side. 3. 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: true is important to trigger the full-screen error page. createError documentation 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: ----------------------
kapa.ai
kapa.ai3w ago
<@1029431292170874910> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
salomon_.
salomon_.OP3w ago
@kapa.ai I added fatal: true but still no full screen error page
kapa.ai
kapa.ai3w ago
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) || "")
// 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"
}
"resolutions": {
"nitropack": "2.9.7"
}
Github Issue #30102 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>
<!-- In your default.vue layout -->
<template>
<div>
<CustomHeader />
<main>
<slot /> <!-- Use slot instead of NuxtPage for error.vue -->
</main>
<CustomFooter />
</div>
</template>
Stack Overflow solution 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
});
// In middleware
throw createError({
statusCode: 404,
statusMessage: 'Page Not Found',
fatal: true
});
Github PR #31518 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>
<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 5. Try Using NuxtErrorBoundary If you're trying to handle errors in a specific component or section, consider using <NuxtErrorBoundary>:
<template>
<NuxtErrorBoundary>
<!-- Your content -->
<template #error="{ error }">
<p>An error occurred: {{ error }}</p>
</template>
</NuxtErrorBoundary>
</template>
<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.
For Hostinger users: Try changing the 404 page from the hosting control panel itself, and put an empty HTML page.
Stack Overflow solution If none of these solutions work, please provide more details about your setup, including your Nuxt version, deployment environment, and any error messages you're seeing in the console. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@1029431292170874910> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?