nuxt / content

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

queryContent during a statically generated page #1762

Open gitFoxCode opened 1 year ago

gitFoxCode commented 1 year ago

Environment


Reproduction

  1. npx nuxi init content-app -t content
  2. Create /components/content/search.vue
  3. Create /content/searcher.md

searcher.md

# Hello, there are articles:
:search

search.vue

<template>
    <div>
        {{ articles }}
    </div>
</template>

<script setup>
const articles = await queryContent('/').find()
</script>

Describe the bug

Everything works very well with the server, but during npm run generate and npm run preview a 404 appears on /searcher. Can't use queryContent during a static page?

Additional context

No response

Logs

No response

farnabaz commented 1 year ago

Do you have a link to search page from the index? This is likely happens because Nuxt generator could not reach to your page with crawling and therefor it did not generate the page. Try adding a link to search page in the index page.

In SSG site, you need to make sure that all contents are reachable by navigating through anchor links.

gitFoxCode commented 1 year ago

@farnabaz I wrote this issue with my project in mind, where in the navigation I had a link to '/blog' in which I used queryContent, which did not work after rendering, it was in the navigation, so nuxt from the home page should also see it, wanting to repeat this error no longer occurs, but I will try to poke around some more

In SSG site, you need to make sure that all contents are reachable by navigating through anchor links.

Why isn't this kind of information in the documentation, it seems to me that this is quite important, in the documentation it says "For every page, Nuxt uses a crawler to generate a corresponding HTML file.". not that the crawler starts from the index and moves through the links

farnabaz commented 1 year ago

I've followed what you described above and it worked when I added a link to the search page in the home page. You might have different setup or something else happens. Do you mind creating a simple reproduction using stackblitz.com/github/nuxt/starter/tree/content?

not that the crawler starts from the index and moves through the links

Of course by default crawler starts from the index page, It it a safe choice to make sure that generator work in a consistent way in all projects. Also there is an option to add other routes as start point for renderer, nuxt.config.ts -> nitro.prerender.routes. see Nitro options: https://nitro.unjs.io/config/#prerender

gitFoxCode commented 1 year ago

@farnabaz Ok, I already know why it doesn't work in my larger project, queryContent I put in a function that should run when the page is opened and retrieve the necessary things, with static generation this function does not work?

reproduction: https://stackblitz.com/edit/github-7erfxk

gitFoxCode commented 1 year ago

@farnabaz Is there any way to make the query dynamic when generating static? I.e., to make this code work after nuxi generate

const searchArticles = (ev) => {
    const searchTerm = ev.target.value
    query.value = {
        path: '/articles', where: {
            title: { $regex: `/${searchTerm}/ig` }
        }, sort: [{ 'article.date': -1 }]
    }
}

Currently, after running searchArticles, only

{
  "message": "You should use slots with <ContentList>",
  "slot": "not-found"
}

is displayed

alexgil1994 commented 1 year ago

I am having similar issues with queryContent on ssg (Nuxt 3.2.2 and latest nuxt content). On run dev and using ssr build has no problems . The error in the console is :

GET http://localhost:3000/blog/books/veronika-decides-to-die 404 (Not Found)
GET http://localhost:3000/api/_content/query/KieiUXwoTD.1677351679705.json?_params=%7B%22first%22:true,%22where%22:%5B%7B%22_path%22:%22/blog/books/veronika-decides-to-die%22%7D%5D,%22sort%22:%5B%7B%22_file%22:1,%22$numeric%22:true%7D%5D%7D 404 (Not Found)

FetchError:  (404 Not Found (/api/_content/query/lVN7LIzOHD.1677351679705.json?_params=%7B%22sort%22:%5B%7B%22date%22:-1%7D%5D,%22where%22:%5B%7B%22_partial%22:false%7D,%7B%22_path%22:%22--REGEX+/^%5C%5C/blog%5C%5C/books/%22%7D%5D%7D))
    at async query.a4e84c45.js:3:6897
    at async setup (index.01782eb2.js:1:697)
florianjs commented 1 year ago

I am having similar issues with queryContent on ssg (Nuxt 3.2.2 and latest nuxt content). On run dev and using ssr build has no problems . The error in the console is :

GET http://localhost:3000/blog/books/veronika-decides-to-die 404 (Not Found)
GET http://localhost:3000/api/_content/query/KieiUXwoTD.1677351679705.json?_params=%7B%22first%22:true,%22where%22:%5B%7B%22_path%22:%22/blog/books/veronika-decides-to-die%22%7D%5D,%22sort%22:%5B%7B%22_file%22:1,%22$numeric%22:true%7D%5D%7D 404 (Not Found)

FetchError:  (404 Not Found (/api/_content/query/lVN7LIzOHD.1677351679705.json?_params=%7B%22sort%22:%5B%7B%22date%22:-1%7D%5D,%22where%22:%5B%7B%22_partial%22:false%7D,%7B%22_path%22:%22--REGEX+/^%5C%5C/blog%5C%5C/books/%22%7D%5D%7D))
    at async query.a4e84c45.js:3:6897
    at async setup (index.01782eb2.js:1:697)

On SSG, you need to add a link to your page :

https://github.com/nuxt/content/issues/1762#issuecomment-1367435661

alexgil1994 commented 1 year ago

I am having similar issues with queryContent on ssg (Nuxt 3.2.2 and latest nuxt content). On run dev and using ssr build has no problems . The error in the console is :

GET http://localhost:3000/blog/books/veronika-decides-to-die 404 (Not Found)
GET http://localhost:3000/api/_content/query/KieiUXwoTD.1677351679705.json?_params=%7B%22first%22:true,%22where%22:%5B%7B%22_path%22:%22/blog/books/veronika-decides-to-die%22%7D%5D,%22sort%22:%5B%7B%22_file%22:1,%22$numeric%22:true%7D%5D%7D 404 (Not Found)

FetchError:  (404 Not Found (/api/_content/query/lVN7LIzOHD.1677351679705.json?_params=%7B%22sort%22:%5B%7B%22date%22:-1%7D%5D,%22where%22:%5B%7B%22_partial%22:false%7D,%7B%22_path%22:%22--REGEX+/^%5C%5C/blog%5C%5C/books/%22%7D%5D%7D))
    at async query.a4e84c45.js:3:6897
    at async setup (index.01782eb2.js:1:697)

On SSG, you need to add a link to your page :

https://github.com/nuxt/content/issues/1762#issuecomment-1367435661

Thanks for trying to help but I don't understand. I do have a link towards the blogs page, both in topbar and footer. Does the search link means something additional?

jvolker commented 1 year ago

I am having similar issues with queryContent on ssg (Nuxt 3.2.2 and latest nuxt content). On run dev and using ssr build has no problems . The error in the console is :

GET http://localhost:3000/blog/books/veronika-decides-to-die 404 (Not Found)
GET http://localhost:3000/api/_content/query/KieiUXwoTD.1677351679705.json?_params=%7B%22first%22:true,%22where%22:%5B%7B%22_path%22:%22/blog/books/veronika-decides-to-die%22%7D%5D,%22sort%22:%5B%7B%22_file%22:1,%22$numeric%22:true%7D%5D%7D 404 (Not Found)

FetchError:  (404 Not Found (/api/_content/query/lVN7LIzOHD.1677351679705.json?_params=%7B%22sort%22:%5B%7B%22date%22:-1%7D%5D,%22where%22:%5B%7B%22_partial%22:false%7D,%7B%22_path%22:%22--REGEX+/^%5C%5C/blog%5C%5C/books/%22%7D%5D%7D))
    at async query.a4e84c45.js:3:6897
    at async setup (index.01782eb2.js:1:697)

On SSG, you need to add a link to your page : #1762 (comment)

Thanks for trying to help but I don't understand. I do have a link towards the blogs page, both in topbar and footer. Does the search link means something additional?

I'm using queryContent() in a component used on the landing page and get a very similar error. I'm not sure how to set that link (since it's on the landing page) or what other workaround I could use?

I'm on Nuxt 3.6.5 and Nuxt content 2.7.2.

Any help would be highly appreciated. Thank you.

jvolker commented 1 year ago

I solved my issue. I think it was a non-existing route linked in a markdown file.

imaginarny commented 10 months ago

I solved my issue. I think it was a non-existing route linked in a markdown file.

Can you elaborate more @jvolker please?

I'm about to implement search, looking for options and thinking it's "not possible" with queryContent as the link with the exact query has to be included somewhere on the page or defined in prerender routes in config. But that is not possible, as the link for the query is dynamic, including `${searchTerm}` so this query can't exist/be prerendered.

So some other way of having something like a sitemap and using that file for search is needed on ssg and do the filtering on your own but it wont be performant. Then still the server route with serverQueryContent would be preferred. That should work with Netlify or Vercel I guess.

jvolker commented 10 months ago

I solved my issue. I think it was a non-existing route linked in a markdown file.

Can you elaborate more @jvolker please?

I don't know if I can be of much help here. I just deleted that link in one of my markdown files. A good way to check if this is causing the errors is to remove all markdown content and restore them bit by bit until it fails. Hope this is helpful.

andreyquerino commented 3 weeks ago

I came across this problem, and ended up being able to perform searches using searchContent().

<script lang="ts" setup>
const searchTerm = ref('')
const result = ref()

async function search() {
  const { data } = await useAsyncData(() => searchContent(searchTerm, {}))
  result.value = data
}
</script>

<template>
<div>
    <input v-model="searchTerm" @input="search()">
    <pre>
      {{ result }}
    </pre>
</div>
</template>

However, it was only returning title and content results and I wanted to get other information as well. So I created a small list with queryContent() and then performed the searches using MiniSearch.

// Get all the data from all the posts content/posts using queryContent() 
const data = ref(await queryContent('posts').find())

// Create list
const dataSearch = ref(get(data).map((el: any) => {
  return {
    id: el._path,
    url: el.url,
    title: el.title,
    image: el.image,
    date: el.date,
    author: el.author,
    category: el.category,
  }
}))

// MiniSearch config
const miniSearch = new MiniSearch({
  fields: ['title'],
  storeFields: ['id', 'url', 'title', 'image', 'date', 'author', 'category'],
  searchOptions: { prefix: true },
})
miniSearch.addAll(get(dataSearch))

// Search
const results = ref(miniSearch.search('lorem ipsum'))