404 page not found content pages unless i hard refresh page
I have a few nuxt content pages like a privacy-policy however if i navigate using a nuxtLink to these pages i get an error 404, if i refresh my browser it however works and fidplays my page. what's the recommended solution to this? I have a catch all page [...slug].vue for rendering these pages do i need to manually specify their urls?
11 Replies
Hi @WiFi Plug. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
This issue is common when using a catch-all route like
Your approach of using a catch-all page (
Implement Document Driven mode in v3. 2. Prerendering/SSG Considerations:
If you are using static site generation (
If you are using SSR (server-side rendering), you do not need to manually specify each URL—the catch-all route will handle them dynamically as long as the content exists. 4. Check for Client/Server Mismatch:
If you are seeing 404s only on client navigation, double-check that your catch-all route is correctly set up and that your content files are in the expected location. Also, ensure you are not missing any configuration that would prevent the router from resolving these routes client-side. Summary:
- For SSR: The catch-all route should work without manual URL specification. - For SSG: You may need to manually add dynamic routes to the prerender config so they are generated and available for client-side navigation. If you follow the document-driven catch-all pattern and ensure your routes are included in the prerendering process (if using SSG), navigation with
Implement Document Driven mode in v3. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
pages/[...slug].vue
to render dynamic content pages (such as privacy-policy) with Nuxt Content. If navigating with <NuxtLink>
results in a 404, but a hard refresh works, it usually means the client-side router cannot resolve the route, often because the static site generation (SSG) or prerendering process did not generate those routes, or the catch-all route is not handling them as expected.
Recommended Solution:
1. Catch-all Route Setup:Your approach of using a catch-all page (
pages/[...slug].vue
) is correct for document-driven content. This page should fetch and render content based on the current route path. For example:
This setup ensures that any route matching the catch-all will attempt to fetch and render the corresponding content file (e.g., /privacy-policy
will look for a matching content file)Implement Document Driven mode in v3. 2. Prerendering/SSG Considerations:
If you are using static site generation (
nuxi generate
), you must ensure that all dynamic routes you want to be available are included in the prerendering process. Otherwise, navigating to them client-side will result in a 404 because the static host doesn't know about those routes. You may need to manually specify these URLs in your Nuxt config under the prerender.routes
option or ensure your content collection is crawled during generation.
3. No Need to Manually Specify URLs for SSR:If you are using SSR (server-side rendering), you do not need to manually specify each URL—the catch-all route will handle them dynamically as long as the content exists. 4. Check for Client/Server Mismatch:
If you are seeing 404s only on client navigation, double-check that your catch-all route is correctly set up and that your content files are in the expected location. Also, ensure you are not missing any configuration that would prevent the router from resolving these routes client-side. Summary:
- For SSR: The catch-all route should work without manual URL specification. - For SSG: You may need to manually add dynamic routes to the prerender config so they are generated and available for client-side navigation. If you follow the document-driven catch-all pattern and ensure your routes are included in the prerendering process (if using SSG), navigation with
<NuxtLink>
should work as expected without 404s for your content pagesImplement Document Driven mode in v3. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai I'm not pre rendering these pages anymore nor using nuxi generate, so in that case do i need to manually add their routes somewhere so the router knows of their existence?
Let me check the knowledge base for you again. One moment! :books:
----------------------
If you are not using static site generation (SSG) or
nuxi generate
, and are instead running your Nuxt app in SSR (server-side rendering) or as a Node.js server, you do not need to manually add the routes for your content pages. Nuxt's file-based routing system will automatically handle dynamic and catch-all routes at runtime, as long as your pages/[...slug].vue
catch-all page is set up correctly. The router will resolve these routes dynamically, and you do not need to specify them anywhere else for the router to recognize them Docs: Routing Docs: Directory Structure - Pages.
Manual route specification is only necessary for SSG/prerendering, where Nuxt needs to know all possible routes at build time. For SSR or a Node.js server, dynamic routes are resolved on demand.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai i'm changing the prefix on the legal pages to the root of my site could that be resulting in the 404 when using nuxtlink to navigate to those pages because it works on a hard refresh?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, changing the
Yes, changing the prefix can result in 404s if your routing or content fetching logic does not match the new paths. Double-check your catch-all route and how you query content to ensure they align with the new root-level URLs generated by the
prefix
for your legal collection to '/'
in your Nuxt Content config will cause the generated paths for those pages to be at the root of your site (e.g., /privacy-policy
instead of /legal/privacy-policy
). This is the intended behavior of the prefix
option Docs: Collection Sources.
However, if you are experiencing 404 errors when navigating to these pages with <NuxtLink>
, but they work on a hard refresh, it suggests a client-side routing issue. This can happen if your catch-all route (pages/[...slug].vue
) or your content fetching logic does not account for the new root-level paths, or if there is a mismatch between the generated route and the actual file path.
Key points from the documentation:
- The prefix
option changes the base URL for the collection’s pages. Setting prefix: '/'
means the content files in content/legal/*.md
will be available at /filename
instead of /legal/filename
Docs: Collection Sources.
- If your catch-all route or content query logic expects the path to include /legal/
, it may not find the content at the new root-level path, resulting in a 404 on client-side navigation.
What to check:
- Ensure your catch-all route and content fetching logic use the correct path (matching the new root-level URLs).
- Make sure there are no conflicting routes or files at the root level that could interfere with these pages.
Summary:Yes, changing the prefix can result in 404s if your routing or content fetching logic does not match the new paths. Double-check your catch-all route and how you query content to ensure they align with the new root-level URLs generated by the
prefix: '/'
setting Docs: Collection Sources.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai "<script setup lang="ts">
import type { PageLink } from '@nuxt/ui-pro'
const route = useRoute()
// Fetch the current page content
const { data: page } = await useAsyncData(route.path, () =>
queryCollection('legal').path(route.path).first()
)
if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
}" im using this in my [...slug].vue page is this right?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Your usage of the following code in your
Since you have set a
- Your code is correct for fetching content from the
pages/[...slug].vue
file is mostly correct for fetching content from the legal
collection based on the current route:
This approach matches the recommended pattern for document-driven mode with Nuxt Content, where you use a catch-all route and fetch the content based on the current path Implement Document Driven mode in v3.
However, there is one important detail:Since you have set a
prefix: '/'
for your legal
collection, the .path(route.path)
call will only work if the route.path
matches the generated path for your legal pages (e.g., /privacy-policy
). If your legal content files are named to match the root-level URLs, this should work as expected.
Summary:- Your code is correct for fetching content from the
legal
collection at the root level, as long as the route.path
matches the path generated by your collection's prefix
setting.
- If you still encounter 404s, double-check that the file names and the prefix
configuration result in the expected root-level paths, and that there are no conflicts with other routes Docs: Collection Sources.
If you follow this pattern, your catch-all route should correctly render your legal pages at the root level.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.