Parsing component references in CMS content in Nuxt
6 Jun 2022
What if you wanted to load CMS content into a Nuxt-powered web page, including parsing any component references in that content?
That's the position I found myself in on a recent project.
Let's load some CMS content via the asyncData
hook, which runs in page components and allows us to merge the fetched content into the page component's data
object.
export default {
data() { return {
//...
}; },
async asyncData() {
let article = await getContent('something'); //returns promise
return {article};
}
}
Let's assume the returned CMS content looks like this (note the reference to a custom component.):
Your first instinct, like mine, might be to hope that v-html
would do the job of parsing component references, as it does for native HTML tags.
Alas, no dice. The component reference is stripped out, and all that's rendered is:
So what to do? The solution is to use the CMS content as the template for a dynamically-created Vue component. So rather than one created within Nuxt (i.e. by creating a file for it in /components
), one instead created via Vue.component()
.
To do this we'll first need to import Vue into our page. Do this right before your component's export:
Now, in our asyncData
hook, we can dynamically create our component.
async asyncData() {
let article = await getContent('something');
let comp = Vue.component('article', {
template: '<div>'+req.data.content+'</div>'
})
return {article: comp};
If your CMS content already has a parent tag wrapping all content, you can omit the div
tags.
Finally, where we want to render the article:
Et voila! We have the equivalent to the v-html approach, except references to custom components will be rendered also.
Did I help you? Feel free to be amazing and buy me a coffee on Ko-fi!