<script lang="ts"> import { VNodeData } from 'vue' import { defineComponent } from '@vue/composition-api' /** * Use this component to render raw SVG content * without the need to use the `v-html` directive * which requires a parent node in Vue 2.x (ex: `<div v-html="..."></div>`). * `<NSvgFragment :src="..." />` will directly render the svg tag with its content. * */ export default defineComponent({ functional: true, props: { src: { type: String, default: '' }, }, render(h, context) { try { const UniversalDOMParser = typeof window === 'undefined' ? require('universal-dom-parser') : DOMParser const svgRoot = new UniversalDOMParser().parseFromString(context.props.src, '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 } const combinedAttributes: VNodeData['attrs'] & { class?: VNodeData['class']; style?: VNodeData['style'] } = { ...(context.data.attrs ?? {}), ...svgAttributes, ...{ class: [context.data.class, (svgAttributes.class as string) || ''], style: [context.data.style, (svgAttributes.style as string) || ''], }, } const { class: classNames, style: styles, ...attributes } = combinedAttributes return h('svg', { ...context.data, attrs: attributes, style: styles, class: classNames, domProps: { innerHTML: `${svgRoot?.innerHTML}`, }, }) } catch (error) { console.error(error) return h('svg', context.data, []) } }, }) </script>