N
Nuxt2mo ago
FoxCode

Can I use useContent() and ContentRendererMarkdown?

Hi, I'm using nuxt-content to generate articles, but in some articles, I wanted to fetch a value from another article. Everything works correctly except for generating the ToC – useContent() ignores everything that is fetched from useAsyncData. How can I change this/delay the ToC generation until useAsyncData has completed (because I think that's where the problem lies)? GetCustom.vue:
<template>
<div class="w-full">
<ContentRendererMarkdown :value="data">
<template #empty>
<p>No content found.</p>
</template>
</ContentRendererMarkdown>
<ContentSlot unwrap="p" />
</div>
</template>
<script setup>
const props = defineProps({
url: String
})
const { data } = await useAsyncData('article', () => queryContent('/external-markdown-files/' + props.url).findOne())
</script>
<template>
<div class="w-full">
<ContentRendererMarkdown :value="data">
<template #empty>
<p>No content found.</p>
</template>
</ContentRendererMarkdown>
<ContentSlot unwrap="p" />
</div>
</template>
<script setup>
const props = defineProps({
url: String
})
const { data } = await useAsyncData('article', () => queryContent('/external-markdown-files/' + props.url).findOne())
</script>
MainArticle.md:
:GetCustom{url="article1"}

## Some heading
:GetCustom{url="article1"}

## Some heading
/external-markdown-files/article1.md:
## Heading 1
test
## Heading 2
## Heading 1
test
## Heading 2
ToC from const { toc } = useContent() only includes headings from MainArticle.md (## Some heading)
No description
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @FoxCode. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the knowledge sources, I can offer some insights into your question about using useContent() and ContentRendererMarkdown with dynamically fetched content. However, it's important to note that the specific scenario you're describing isn't directly addressed in the provided documents. The issue you're experiencing with the Table of Contents (ToC) not including headings from dynamically fetched content is likely due to how useContent() works in conjunction with the document-driven mode of Nuxt Content. According to the useContent() documentation (https://content.nuxt.com/document-driven/use-content/), this composable is designed to give access to the current page, surrounding pages, and global data when the document-driven mode is enabled. It's not specifically designed to work with dynamically fetched content using useAsyncData. The toc property from useContent() is computed based on the current page's content, which is why it only includes headings from MainArticle.md and not from the dynamically fetched article1.md. To address this issue, you might need to consider an alternative approach: 1. Instead of using useContent() for the ToC, you could create a custom ToC component that processes the combined content after all async operations are complete. 2. You could use the <ContentRenderer> (https://content.nuxt.com/components/content-renderer/#slots) component with a custom slot to render your content, including both the main article and the fetched content. This might allow you to generate a ToC from the combined content. Here's a potential approach using <ContentRenderer>:
<script setup>
const route = useRoute()
const { data: mainArticle } = await useAsyncData('main-article', () => queryContent(route.path).findOne())
const { data: customArticle } = await useAsyncData('custom-article', () => queryContent('/external-markdown-files/article1').findOne())

// Combine the content
const combinedContent = computed(() => {
if (mainArticle.value && customArticle.value) {
return {
...mainArticle.value,
body: {
...mainArticle.value.body,
children: [...customArticle.value.body.children, ...mainArticle.value.body.children]
}
}
}
return mainArticle.value
})
</script>

<template>
<ContentRenderer :value="combinedContent">
<!-- Custom rendering logic here -->
</ContentRenderer>
</template>
<script setup>
const route = useRoute()
const { data: mainArticle } = await useAsyncData('main-article', () => queryContent(route.path).findOne())
const { data: customArticle } = await useAsyncData('custom-article', () => queryContent('/external-markdown-files/article1').findOne())

// Combine the content
const combinedContent = computed(() => {
if (mainArticle.value && customArticle.value) {
return {
...mainArticle.value,
body: {
...mainArticle.value.body,
children: [...customArticle.value.body.children, ...mainArticle.value.body.children]
}
}
}
return mainArticle.value
})
</script>

<template>
<ContentRenderer :value="combinedContent">
<!-- Custom rendering logic here -->
</ContentRenderer>
</template>
This approach combines the content before rendering, which might allow for a more comprehensive ToC generation. However, please note that this is a theoretical solution based on the available documentation, and you may need to adjust it based on your specific setup and requirements. For a more definitive solution, you might want to consider asking this question in the Nuxt GitHub issues (https://github.com/nuxt/nuxt/issues) or the Nuxt community forums, as it seems to be a specific use case that isn't directly covered in the current documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@363971301947342848> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Want results from more Discord servers?
Add your server