Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nuxt render function for a string of HTML that contains Vue components

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.

like image 908
Drew Baker Avatar asked May 06 '19 23:05

Drew Baker


People also ask

How do I use Vue components in Nuxt?

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.

How do I render components in Vue?

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.

Can you use JSX with Vue?

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 .

Is Nuxt good for spa?

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.

Does the last render function work in nuxt?

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?

How to render the HTML string as real DOM elements in Vue?

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.

How to render pure HTML without JS in nuxt?

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.

What is the V-HTML directive in Vue?

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.


Video Answer


1 Answers

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.

like image 138
Romain Ortega Avatar answered Sep 27 '22 22:09

Romain Ortega