Skip to content

Instantly share code, notes, and snippets.

@nash403
Last active June 9, 2025 21:31
Show Gist options
  • Save nash403/9e7746f9eda859155c8b111db5f8ed3b to your computer and use it in GitHub Desktop.
Save nash403/9e7746f9eda859155c8b111db5f8ed3b to your computer and use it in GitHub Desktop.
Vue component that render raw SVG content like with `v-html` but without the need of an extra root element.
<script lang="ts">
import { h, VNodeData, mergeProps, defineComponent } from 'vue'
/**
* Use this component to render raw SVG content
* without the need to use the `v-html` directive
* which requires a parent node in Vue (ex: `<div v-html="..."></div>`).
* `<NSvgFragment :content="..." />` will directly render the svg tag with its content.
* */
export default defineComponent({
props: {
content: { type: String, default: '' },
},
setup(props, context) {
try {
const UniversalDOMParser = typeof window === 'undefined' ? require('universal-dom-parser') : DOMParser
const svgRoot = new UniversalDOMParser().parseFromString(props.content, 'image/svg+xml').firstChild as Element
const svgAttributes = {} as { [key: string]: unknown }
for (const attribute of Array.from(svgRoot?.attributes ?? [])) {
svgAttributes[attribute.name] = attribute.value
}
return () => h('svg', mergeProps(context.attrs, {
...svgAttributes,
domProps: {
innerHTML: `${svgRoot?.innerHTML}`,
},
}))
} catch (error) {
console.error(error)
return () => h('svg', props)
}
},
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment