content
content copied to clipboard
Nuxt content-driven site problem: queryContent pages giving 404s during generate
Environment
- Operating System:
Darwin - Node Version:
v18.13.0 - Nuxt Version:
3.11.1 - CLI Version:
3.11.1 - Nitro Version:
2.9.4 - Package Manager:
[email protected] - Builder:
- - User Config:
modules,app,content,tailwindcss,postcss,image,colorMode,runtimeConfig - Runtime Modules:
@nuxt/[email protected],@nuxtjs/[email protected],@nuxt/[email protected],[email protected],@nuxtjs/[email protected] - Build Modules:
-
Reproduction
I asked this as a question in the Discussion section a few months ago: https://github.com/nuxt/nuxt/discussions/26475
My static site is https://oberbrunner.com and the git repo is at https://github.com/garyo/oberbrunner-website.git. Check out version 8114db28b44b136 of that repo (that's before I applied a workaround), then do:
pnpm install
pnpm generate
and you will get a set of errors during the prerender:
Errors prerendering:
├─ /api/_content/query/wyAI10pxT3.1711366156783.json (1ms)
│ ├── Error: [404] Document not found!
│ └── Linked from /articles/tags/programming
├─ /api/_content/query/3wG2XPSOCP.1711366156783.json (1ms)
│ ├── Error: [404] Document not found!
│ └── Linked from /articles/tags/async
├─ /api/_content/query/V075q5TyMx.1711366156783.json (1ms)
│ ├── Error: [404] Document not found!
│ └── Linked from /articles/tags/society & culture
├─ /api/_content/query/oeZgEOdCy4.1711366156783.json (2ms)
│ ├── Error: [404] Document not found!
Describe the bug
I can't see what is causing those 404s. More complete logs are in the discussion linked above. It prevents the site from being built. Clearly related to dynamic content somehow; maybe the query results are being stored under different names?
Additional context
No response
Logs
See the discussion at https://github.com/nuxt/nuxt/discussions/26475 for complete logs.
I did try pnpm upgrade --latest but I get the same results.
do you have ssr: false and target: static in your nuxt.config.ts?
you may need the clientDB:
content: {
experimental: {
clientDB: true
},
},
There is no more target: static in nuxt 3, I think (I added it but it didn't change anything). Using ssr: false results in missing images. ssr: true (the default) is normally used for a static site, right?
I did try adding experimental.clientDB: true but it didn't change anything.
That is because the content-driven mode consider what appears in pages (routes) should have corresponding file in content. nuxt generate pre-render all the routes -> nuxt-content tries but failed.
Solution
By now, I haven't see a proper configuration option to manually include or exclude some paths for nuxt-content.
A workaround is using nuxt build instead of nuxt generate and sets all routes with content to {prerender: true}. swr could be set to enable cache for some time.
Be careful that using
swrmight cause some issues in dev mode. So I cancel the rules in dev mode (default 2 years of cache maxAge if true)
// nuxt.config.ts
$production: {
routeRules: {
'/': { swr: 900 },
'/blog': { swr: 900 },
'/blog/**': { prerender: true, swr: 900 },
'/api/**': { isr: false },
},
},
$development: {
routeRules: {
'/api/**': { isr: false },
},
},
This issue was driving me insane, but I finally have it sorted. My site is a mix of markdown content in /content and vue files in /pages.
In the script setup of each of the vue files, add the following, removing those pages from content-driven.
definePageMeta({ documentDriven: { page: false, surround: false, }, });
Sadly, that didn't do it for me -- see https://www.reddit.com/r/Nuxt/comments/14t1fg9/comment/l5gx4a3/ But I'm glad it worked for you!
I think the the problem has to do with this in the nuxt.config.ts:
content: {
documentDriven: true
},
It's being set globally. So it's going to affect the entire nuxt configuration globally. It will try to inject into all vue pages it finds. The documentation wasn't really clear, unfortunately, on this. But it's probably why it's an "option" to include. To clarify it will inject in all vue page files (and not just the slug vue file) - which is exactly what you don't want. I personally feel this is a bug, but I can see "why" it's affecting all vue pages you don't want it to affect. I feel that setting documentDriven globally is only for people who aren't mixing and matching content with pages.
I would eliminate "documentDriven: true" from the nuxt.config.ts file altogether and simply set it in the respective slug file(s) where you want it to apply. Ie:
definePageMeta({
documentDriven: true
})
This would also eliminate the need to set it "false" or override it on a page by page basis.
So it's going to affect the entire nuxt configuration globally. It will try to inject into all vue pages it finds.
This seems promising! If I remove it from my nuxt.config.ts, then I'm not sure where to apply it. I'm using it to create the site from my content dir which is just a bunch of .md files:
% t content
content
├── 1.index.md
├── 2.articles.md
├── 3.photos.md
└── articles
├── 1.new-blog.md
├── 2.js-looping.md
├── 3.entropy-and-passwords.md
├── 4.js-promises.md
└── 5.climate-change-personal.md
My pages folder, which is where the dynamic content is, is just one slug:
├── pages
│ └── articles
│ └── tags
│ └── [tag].vue
I note that if I just remove that directive from my nuxt.config.ts then when generating the site, it gets a 404 on / which makes sense since that is supposed to come from my content/1.index.md.
For completeness, here's most of my site structure:
% t -I node_modules
.
├── app.config.ts
├── app.vue
├── assets
│ ├── css
│ │ └── main.css
│ ├── favicon-16.png
│ ├── favicon-32.png
│ └── favicon.png
├── components
│ ├── AppFooter.vue
│ ├── ColorModeSwitch.vue
│ ├── content
│ │ ├── ArticlesList.vue
│ │ ├── ArticlesListItem.vue
│ │ ├── EmbedIframe.vue
│ │ ├── Gallery.vue
│ │ ├── HeroImage.vue
│ │ ├── ShowBreakpoint.vue
│ │ ├── Tag.vue
│ │ └── TagsList.vue
│ ├── MainNav.vue
│ └── SocialIcons.vue
├── composables
│ ├── date.ts
│ ├── useArticle.ts
│ └── useSiteMeta.ts
├── content
│ ├── 1.index.md
│ ├── 2.articles.md
│ └── articles
│ ├── 1.new-blog.md
│ ├── 2.js-looping.md
├── deploy.sh
├── layouts
│ ├── custom.vue
│ └── default.vue
├── nuxt.config.ts
├── package.json
├── pages
│ └── articles
│ └── tags
│ └── [tag].vue
├── plugins
│ └── vue-gtag.client.js
├── pnpm-lock.yaml
├── public
│ ├── articles
│ │ ├── climate-change-stripes.png
│ │ ├── key-vines.jpg
│ │ ├── looping.jpg
│ │ └── mechanism.jpg
│ ├── favicon.ico
│ ├── headshot.jpg
│ └── ukiyo-e-abstract.jpg
├── README.md
├── tailwind.config.js
└── tsconfig.json
So where should I apply the directive? Any help appreciated!
This issue was driving me insane, but I finally have it sorted. My site is a mix of markdown content in /content and vue files in /pages.
In the script setup of each of the vue files, add the following, removing those pages from content-driven.
definePageMeta({ documentDriven: { page: false, surround: false, }, });
!!! In that case the layouts are not working. Any workaround?
I think the the problem has to do with this in the nuxt.config.ts:
content: { documentDriven: true },It's being set globally. So it's going to affect the entire nuxt configuration globally. It will try to inject into all vue pages it finds. The documentation wasn't really clear, unfortunately, on this. But it's probably why it's an "option" to include. To clarify it will inject in all vue page files (and not just the slug vue file) - which is exactly what you don't want. I personally feel this is a bug, but I can see "why" it's affecting all vue pages you don't want it to affect. I feel that setting documentDriven globally is only for people who aren't mixing and matching content with pages.
I would eliminate "documentDriven: true" from the nuxt.config.ts file altogether and simply set it in the respective slug file(s) where you want it to apply. Ie:
definePageMeta({ documentDriven: true })This would also eliminate the need to set it "false" or override it on a page by page basis.
!!!!! I feel very fortunate to have stumbled upon your solution. It has indeed helped me a lot and saved me from being insane
The documentDriven mode is a big issue in its current experimental state when using both /pages and /content in tandem. The workaround is to set documentDriven: false for all slug files you may have. Remember that you cannot apply it in layout files.
Set this in your slug file(s):
definePageMeta({
documentDriven: true,
});
And in your nuxt.config.js:
content: {
documentDriven: false,
},
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.
@nsina
definePageMeta({
documentDriven: true,
});
works for me, thanks