Reputation: 274
Hi have been having troubling importing inline svgs into my nuxt3 vite project. Any advice would be much appreciated.
i found this works <img src="~/assets/images/icons/push-icon-chatops.svg" />
however i need an inline item. so i would do something like this <div v-html="rawNuxtLogo" />
and doing something like this(require doesnt work in vite) .
setup(props) {
const currentIcon = computed(() => {
return defineAsyncComponent(() =>
import(`~/assets/images/icons/push-icon-chatops.svg'?inline`)
);
}).value;
return {
currentIcon,
};
},
however i found that vite does imports weirdly and the result is either the url string showing in the v-html or a object that doesnt read
i am trying to use this plugin with no success.
https://github.com/nuxt-community/svg-module
Upvotes: 6
Views: 12354
Reputation: 2786
Working without any additional module
<script lang="ts" setup>
import { onMounted } from 'vue'
const props = defineProps<{ url: string }>()
const svgString = ref('')
onMounted(() => {
fetch(props.url)
.then(response => response.text())
.then((svg) => {
const parser = new DOMParser()
const doc = parser.parseFromString(svg, 'image/svg+xml')
const svgElement = doc.documentElement
const svgContainer = document.createElement('div')
svgContainer.appendChild(svgElement)
svgString.value = svgContainer.innerHTML
})
})
</script>
<template>
<div v-html="svgString" />
</template>
Upvotes: 0
Reputation: 11
This solution worked for me to import it dynamically, using vite-svg-loader:
<template>
<component :is="icon" />
</template>
<script setup>
import { defineAsyncComponent } from 'vue'
const props = defineProps({
name: {
type: String,
default: 'logo'
}
})
const icons = import.meta.glob(`@/**/*.svg`)
const icon = computed(() => {
return defineAsyncComponent(() => {
return icons[`/assets/images/icons/${props.name}.svg`]()
})
})
</script>
Upvotes: 1
Reputation: 141
Inline Svg images in nuxt 3, without using any library, such as vite-svg-loader
or nuxt-svgo
.
<template>
<span v-html="icon" />
</template>
<script lang="ts" setup>
import { filename } from 'pathe/utils';
const props = defineProps<{
icon: string;
}>();
// Auto-load icons as raw
const glob = import.meta.glob('~/assets/*.svg', { as: 'raw' });
const images = Object.fromEntries(
Object.entries(glob)
.map(([key, value]: [string, any]) => [filename(key), value]))
// Lazily load the icon
const icon = props.icon && (await images?.[props.icon]?.());
</script>
Upvotes: 2
Reputation: 2784
For TS Nuxt 3 projects it would be like this.
nuxt.config.ts
file:
import svgLoader from 'vite-svg-loader'
export default defineNuxtConfig({
// Rest of your config.
vite: {
plugins: [
svgLoader({
// Your settings.
}),
],
},
})
Example for a component:
<template>
<div>
<ArrowLeft />
</div>
</template>
<script setup lang="ts">
import ArrowLeft from '../assets/svg/arrow-left.svg?component'
</script>
Note that the ?component
in the end is important, otherwise TS will complain.
Plugin Documentation: vite-svg-loader
Upvotes: 3
Reputation: 274
so its seems that vite is actually not compatiable with the @nuxtjs/svg
plugin. so the answer is to rather install a vite specific plugin in this case i installed vite plugin then do this
vite: {
plugins: [
svgLoader()
]
},
Upvotes: 9