vue-dompurify-html
A "safe" replacement for the v-html
directive. The HTML code is
sanitized with DOMPurify before being interpreted.
This is only a small wrapper around DOMPurify to ease its usage in a Vue app.
You should take a look at the
DOMPurify Security Goals & Threat Model
to understand what are the limitations and possibilities.
If you are looking for a version compatible with Vue 3 checkout the main branch.
Installation
npm install vue-dompurify-html@vue-legacy
Usage
import Vue from 'vue'
import VueDOMPurifyHTML from 'vue-dompurify-html'
Vue.use(VueDOMPurifyHTML)
new Vue({
el: '#app',
data: {
rawHtml: '<span style="color: red">This should be red.</span>'
}
})
In your template:
<div id="app">
<div v-dompurify-html="rawHtml"></div>
</div>
You can also define your DOMPurify configurations:
import Vue from 'vue'
import VueDOMPurifyHTML from 'vue-dompurify-html'
Vue.use(VueDOMPurifyHTML, {
namedConfigurations: {
'svg': {
USE_PROFILES: { svg: true }
},
'mathml': {
USE_PROFILES: { mathMl: true }
},
}
});
new Vue({
el: '#app',
data: {
rawHtml: '<span style="color: red">This should be red.</span>',
svgContent: '<svg><rect height="50"></rect></svg>'
}
})
Your configuration keys can then be used as an argument of the directive:
<div id="app">
<div v-dompurify-html="rawHtml"></div>
<div v-dompurify-html:svg="svgContent"></div>
</div>
Alternatively, you can define a default DOMPurify configuration:
import Vue from 'vue'
import VueDOMPurifyHTML from 'vue-dompurify-html'
Vue.use(VueDOMPurifyHTML, {
default: {
USE_PROFILES: { html: false }
}
});
new Vue({
el: '#app',
data: {
rawHtml: '<span style="color: red">This should not be red.</span>'
}
})
The default
DOMPurify configuration will be used:
<div id="app">
<div v-dompurify-html="rawHtml"></div>
</div>
There is also the possibility to set-up DOMPurify hooks:
import { createApp } from 'vue'
import VueDOMPurifyHTML from 'vue-dompurify-html'
const app = createApp({
data: () => ({
rawHtml: '<span style="color: red">This should be red.</span>'
})
});
app.use(VueDOMPurifyHTML, {
hooks: {
uponSanitizeElement: (currentNode) => {
// Do something with the node
}
}
});
app.mount('#app');
Usage with Nuxt
Client side
The usage is similar than when directly using Vue.
Define a new Nuxt plugin to import and setup the directive to your liking:
import Vue from 'vue';
import VueDOMPurifyHTML from 'vue-dompurify-html';
Vue.use(VueDOMPurifyHTML);
and then tell Nuxt to use it as client-side plugin in your Nuxt config:
export default {
plugins: [{ src: '~/plugins/dompurify', mode: 'client' }]
}
Server side
The usage is similar than when directly using Vue but you need to setup DOMPurify to work with Node.
Install this package, DOMPurify and JSDOM:
npm install vue-dompurify-html@vue-legacy dompurify jsdom
In your Nuxt config you will need to setup a "server-side" directive:
export default {
render: {
bundleRenderer: {
directives: {
'dompurify-html': (el, dir) => {
const insertHook = buildVueDompurifyHTMLDirective(
{},
() => {
const window = new JSDOM('').window;
return createDOMPurify(window);
}
).inserted;
insertHook(el, dir);
el.data.domProps = { innerHTML: el.innerHTML };
}
}
}
}
}
Note that if you are not using injectScripts: false
in your Nuxt config you will also need to register a client-side plugin as described just before.