nuxt / content

The file-based CMS for your Nuxt application, powered by Markdown and Vue components.
https://content.nuxt.com
MIT License
3k stars 605 forks source link

Nuxt content-driven site problem: queryContent pages giving 404s during generate #2644

Open garyo opened 1 month ago

garyo commented 1 month ago

Environment

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.

garyo commented 1 month ago

I did try pnpm upgrade --latest but I get the same results.

efernau commented 4 weeks ago

do you have ssr: false and target: static in your nuxt.config.ts?

you may need the clientDB:

content: {
    experimental: {
      clientDB: true
    },
  },
garyo commented 4 weeks ago

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.

Purple-CSGO commented 4 weeks ago

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 swr might 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 },
    },
  },
resolutionathens commented 1 week ago

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, }, });

garyo commented 1 week ago

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!

Rexa-Raven commented 3 days ago

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.

garyo commented 3 days ago

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.

garyo commented 3 days ago

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!

JiProchazka commented 1 day ago

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?