I'm trying to solve this for Nuxt
Codesandbox of a WIP not working: https://codesandbox.io/s/zw26v3940m
OK, so I have WordPress as a CMS, and it's outputting a bunch of HTML. A sample of the HTML looks like this:
'<h2>A heading tag</h2>
<site-banner image="{}" id="123">Slot text here</site-banner>
<p>some text</p>'
Notice that it contains a Vue component <site-banner>
that has some props on it (the image
prop is a JSON object I left out for brevity). That component is registered globally.
I have a component that we wrote, called <wp-content>
that works great in Vue, but doesn't work in Nuxt. Note the two render functions, one is for Vue the other is for Nuxt (obviously this is for examples sake, I wouldn't use both).
export default {
props: {
html: {
type: String,
default: ""
}
},
render(h, context) {
// Worked great in Vue
return h({ template: this.html })
}
render(createElement, context) {
// Kind of works in Nuxt, but doesn't render Vue components at all
return createElement("div", { domProps: { innerHTML: this.html } })
}
}
So the last render function works in Nuxt except it won't actually render the Vue components in this.html
, it just puts them on the page as HTML.
So how do I do this in Nuxt? I want to take a string of HTML from the server, and render it on the page, and turn any registered Vue components into proper full-blown Vue components. Basically a little "VueifyThis(html)" factory.
In order to use Vue plugins we need to create a Nuxt plugin and we do this by creating a . js file in the /plugins folder. We then paste in the code that we need to use the plugin. We import Vue and VTooltip and then tell Vue to use the VTooltip.
Each Vue component implements a render function. Most of the time, the function will be created by the Vue compiler. When you specify a template on your component, the content of this template will be processed by the Vue compiler that will return a render function.
If you have worked with JSX before, do note that Vue JSX transform is different from React's JSX transform, so you can't use React's JSX transform in Vue applications. Some notable differences from React JSX include: You can use HTML attributes such as class and for as props - no need to use className or htmlFor .
When combined with headless platform such as CrafterCMS, Nuxt can provide a framework to build highly-performant web applications and SPAs. This article is an introductory review of NuxtJS, a powerful framework on top of Vue for building modern web applications.
So the last render function works in Nuxt except it won't actually render the Vue components in this.html, it just puts them on the page as HTML. So how do I do this in Nuxt?
Learn, how to render the html string as real dom elements in Vue. Note: If we try to use vue template syntax { { }} to render an html string, vue will be treated as a plain text instead of real html. Vue has a built-in v-html directive by using that we can render a html string. The v-html directive is a vue version of browser innerHTML property.
Adds the <script> for Nuxt bundles, set it to false to render pure HTML without JS (available with 2.8.0+) Adds prefetch and preload links for faster initial page load time. You may want to only disable this option if you have many pages and routes. This option is automatically set based on global ssr value if not provided.
The v-html directive is a vue version of browser innerHTML property. This above code will render an h1 element with red color inside the div. Note: By using the v-html directive you are vulnerable to cross-site scripting attacks (XSS), to prevent from it sanitize your html before passing it to v-html directive.
This is how I did it with Nuxt 3 :
<script setup lang="ts">
import { h } from 'vue';
const props = defineProps<{
class: string;
HTML: string
}>();
const VNode = () => h('div', { class: props.class, innerHTML: props.HTML })
</script>
<template>
<VNode />
</template>
There was not need to update nuxt.config.ts
.
Hopefully it will help some of you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With