content icon indicating copy to clipboard operation
content copied to clipboard

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

Open garyo opened this issue 1 year ago • 12 comments

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 avatar May 24 '24 15:05 garyo

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

garyo avatar May 24 '24 16:05 garyo

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

you may need the clientDB:

content: {
    experimental: {
      clientDB: true
    },
  },

efernau avatar May 28 '24 02:05 efernau

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.

garyo avatar May 28 '24 10:05 garyo

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

Purple-CSGO avatar May 28 '24 11:05 Purple-CSGO

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

resolutionathens avatar Jun 18 '24 18:06 resolutionathens

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!

garyo avatar Jun 18 '24 19:06 garyo

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.

Rexa-Raven avatar Jun 23 '24 14:06 Rexa-Raven

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 avatar Jun 23 '24 15:06 garyo

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!

garyo avatar Jun 23 '24 15:06 garyo

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?

JiProchazka avatar Jun 25 '24 13:06 JiProchazka

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

lime2008 avatar Jul 22 '24 07:07 lime2008

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

nsina avatar Oct 14 '24 03:10 nsina

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.

github-actions[bot] avatar Dec 13 '24 04:12 github-actions[bot]

@nsina

definePageMeta({
   documentDriven: true,
});

works for me, thanks

azabroflovski avatar Jan 02 '25 18:01 azabroflovski