content
content copied to clipboard
Content API giving 404 on generate build
Environment
- Operating System:
Darwin
- Node Version:
v16.18.0
- Nuxt Version:
3.4.3
- Nitro Version:
2.4.0
- Package Manager:
[email protected]
- Builder:
vite
- User Config:
modules
- Runtime Modules:
@nuxt/[email protected]
- Build Modules:
-
Reproduction
https://github.com/Tragio/nuxt-content-repro
yarn generate && yarn preview
first selects works, and subsequent selects return 404.
yarn dev
/ yarn build
works just fine.
Describe the bug
Nuxt Content with filter works just fine on dev, but as soon I generate the build it stops working properly.
Already tried all solutions provided here: https://github.com/nuxt/content/issues/1798
Additional context
No response
Logs
No response
CC: @farnabaz
You are generating a static website, which means that there will be no APIs. When you change the select input content will execute query and requests server to get the right data, but instead of data it receives 404.
You should enable the experimental clientdb
feature to allow the content module to run queries inside the browser
export default defineNuxtConfig({
content: {
experimental: {
clientDb: true
}
}
})
You are generating a static website, which means that there will be no APIs. When you change the select input content will execute query and requests server to get the right data, but instead of data it receives 404.
You should enable the experimental
clientdb
feature to allow the content module to run queries inside the browserexport default defineNuxtConfig({ content: { experimental: { clientDb: true } } })
Having the same problem as @Tragio this experimental clientdb setting doesn't fix my problem still getting an 404.
@farnabaz thank you very much for your reply 🙏 yes I have tried that before creating this issue.
By putting that in my code reproduction has exactly the same outcome, like @jeffreyvdhondel also has.
I see, Sorry for my partial explanation Currently module does not support hybrid mode, which means that you can only use it on full SSG or without SSR so if you want to use client-side querying, you need to disable SSR
export default defineNuxtConfig({
ssr: false,
content: {
experimental: {
clientDb: true
}
}
})
I can imagine this is not exactly what you want to do, But the hybrid feature is yet to be implemented, thats why clientDB
also is in experimental mode
But for what i understand we both don't want to use hybrid mode but just full static. But that doesn't pre-render component logic?
Content module creates a list out of all queries that executed in generation phase and store them as static files.
But as you can see in this example, queries for Team A
, Team B
and Team C
won't execute in generation. They will execute only if user select a value from select input. In situations like this, there is no way for module to guess the query.
But if you look into to cached json file the data is there.
Indeed, cached json is just a list of all contents. In production (inside server API) it is used to find the corresponding files based on query. But in SSG there is no server API to find the contents. So all the queries should store as separate file in generation phase.
@farnabaz so we can't use nuxi generate
in any way, right? At the moment my requirement was to have a static server.
I tried nuxi generate
with the following and the result was the same.
export default defineNuxtConfig({
ssr: false,
content: {
experimental: {
clientDb: true
}
}
})
@Tragio it's working for me using these settings (note the casing on clientDB
)
export default defineNuxtConfig({
ssr: false,
content: {
experimental: {
clientDB: true
}
}
})
Yeah that was the issue :)
Ahh it was a copy-paste issue 😋 for me it is also working. @farnabaz I was about to create a PR, but not sure if nitro.preset: 'service-worker'
does anything for the static deployment. If it should be replaced for what is there or added 🤔 maybe would be better for you to update the docs 🙏
defineNuxtConfig({
ssr: false,
nitro: {
preset: 'service-worker'
}
})
by:
defineNuxtConfig({
ssr: false,
content: {
experimental: {
clientDB: true
}
}
})
I am facing the same issue with a search page that accepts user input via a text field to perform a search on the contents. The experimental clientDB fixes the issue, but degrades SEO as SSR has to be fully disabled.
It would be great to be able to force using the clientDB per query while still using SSR. I'll try to get this done for the project I'm working on.
I'm at the same stage as @semiaddict - I'm building a company website with mostly static content. Don't want to disable SSR globally but need to implement a search page with user input.
Would be great if someone came up with a solution.
@philkaracho, after looking at the code responsible for using the clientDB, it seems too big a trouble to get it working for my use case as the client-db code is not exported and can't be used outside the content module, and the corresponding composables are also not auto-imported.
Since I only needed this in the search page, I opted for adding the necessary data from the content in the search index. FYI, I am using MiniSearch, which allows adding extra data to the indexed content.
@semiaddict Thanks for getting back on this!
I went the same route: fetching all the content once and performing the search locally. MiniSearch looks promising, thanks for sharing that!
For someone interested, we fixed this issue in this way:
- create dynamic slug page [...slug].vue (https://content.nuxtjs.org/examples/navigation/use-route)
<script setup>
const { path } = useRoute();
const { data } = await useAsyncData(`content-${path}`, () => {
return queryContent().where({ _path: path }).findOne()
})
</script>
<template>
<main class="prose text-left">
<ContentRenderer v-if="data" :value="data" />
</main>
</template>
- Create a module that scan the 'content' directory and dynamically incorporates its paths into the prerendering routes
import { defineNuxtModule } from '@nuxt/kit';
import fs from 'fs/promises';
import path from 'path';
async function listFilesInDirectory(directory: string, prefix = '') {
const entries = await fs.readdir(directory, { withFileTypes: true });
// Use map() to perform the following actions for each entry in the directory
const files: any = await Promise.all(entries.map(async (entry) => {
const fullPath = path.join(directory, entry.name);
const relativePath = path.join(prefix, entry.name);
if (entry.isDirectory()) {
// If the entry is a directory, recursively list the files in it
return listFilesInDirectory(fullPath, relativePath);
} else {
// If the entry is a file, remove the extension, prepend a slash, and remove number and dot prefix
const ext = path.extname(entry.name);
const nameWithoutExtension = path.basename(entry.name, ext);
const nameWithoutNumberPrefix = nameWithoutExtension.replace(/^\d+\.\s/, '');
// Check if the name ends with 'index', if so, replace it with '/'
if (nameWithoutNumberPrefix === 'index') {
return path.join('/', prefix, '/');
}
return '/' + path.join(prefix, nameWithoutNumberPrefix);
}
}));
// Flatten the array and return it
return Array.prototype.concat(...files);
}
export default defineNuxtModule({
async setup(_moduleOptions, nuxt) {
const paths = await listFilesInDirectory('./content');
nuxt.hook('nitro:config', (nitroConfig) => {
nitroConfig.prerender.routes = nitroConfig.prerender.routes || [];
nitroConfig.prerender.routes?.push(...paths);
});
}
});
I hope this helps, however I don't think it solves the initial reported problem ...
I'm sure the nuxt team is already working on a definitive solution
If you are facing issues with generating a static HTML file and receiving a 404 error, you need to add one of your routes to the static generation in nuxt.config.ts. After doing this, all files will be generated correctly.
export default defineNuxtConfig({
generate: {
routes: ["/test-route/test"], // one of routes getting 404
},
})
@parsajiravand how to make the content & pages render ? especially the slug.vue cases? for static hosting,.
I have the following route rules:
routeRules: {
'/**': { prerender: true },
'/dashboard/**': { ssr: false }
},
Everything works fine. However, when opening a blog, the blog doesn't load. It does load after a refresh. How can I fix this issue?
I'm having similar issues where something like:
[nitro 17:41:40] ├─ /api/_content/query/2w8OxZpsdg.1692308491351.json (47ms) (Error: [404] Document not found!)
showed up when running pnpm generate
. And disabling SSR along with enabling clientDB solves the problem. But this also break the nuxt-image module and I'm not seeing any images or pictures. Any update or ideas on this problem?
But this also break the nuxt-image module
This is pretty much my day-to-day experience with Nuxt. Something always seems to break.
It's really quite depressing when you've put so much work in to craft a website.
FWIW on Netlify what worked for me was:
- setting
ssr
totrue
- changing the Netlify build command to
npm run build
(vsgenerate
) - removing the Netlify
NITRO_PREFIX=netlify-edge
environment variable
And FWIW Lighthouse performance shot up from mid 60s to 96 (98 on mobile!):
Site link here.
I somehow get this problem solved, but with different ways in different versions of Nuxt.
In the latest Nuxt 3.7.3, the 404 error should point to a specific file that is missing from your content. Say, for me I have a content/blog
directory for holding all the blog posts, and set up a pages/blog/[slug].vue
for rendering the blog page and a pages/blog/index.vue
to query content in that folder and render a index page. This should work fine in the Nuxt 3.7.3, but for some reason, in earlier versions of Nuxt, you might need want to try one of the two workarounds:
- Add a
content/blog/index.md
as a placeholder and manage to filter that out inpages/blog/index.vue
- Move
pages/blog/index.vue
topages/blog.vue
and also add a placeholdercontent/blog.md
. You only need to make sure that the query path in yourpages/blog.vue
is set to/blog/
instead of/blog
. (Note that this breaks at least in Nuxt 3.7.3 as it will make the child pages not accessible, but works in some earlier verions)
I'm having similar issues where something like:
[nitro 17:41:40] ├─ /api/_content/query/2w8OxZpsdg.1692308491351.json (47ms) (Error: [404] Document not found!)
showed up when running
pnpm generate
. And disabling SSR along with enabling clientDB solves the problem. But this also break the nuxt-image module and I'm not seeing any images or pictures. Any update or ideas on this problem?
Have you tried this? https://image.nuxt.com/advanced/static-images
I'm having similar issues where something like:
[nitro 17:41:40] ├─ /api/_content/query/2w8OxZpsdg.1692308491351.json (47ms) (Error: [404] Document not found!)
showed up when running
pnpm generate
. And disabling SSR along with enabling clientDB solves the problem. But this also break the nuxt-image module and I'm not seeing any images or pictures. Any update or ideas on this problem?Have you tried this? https://image.nuxt.com/advanced/static-images
Thanks for your suggestion. I didn't see that page at the time. But now I got the problem solved with static site generating so I would rather stick to it and won't bother pre-rendering the images. Thanks again anyway.
FWIW on Netlify what worked for me was:
- setting
ssr
totrue
- changing the Netlify build command to
npm run build
(vsgenerate
)- removing the Netlify
NITRO_PREFIX=netlify-edge
environment variableAnd FWIW Lighthouse performance shot up from mid 60s to 96 (98 on mobile!):
Site link here.
@davestewart And serving it using node .output/server/index.mjs
? Not as static HTML/JS ?