DEV Community

aronsantha
aronsantha

Posted on

> Dynamic SVG in Vue with Vite

Let me show you a super useful implementation of Vite's Glob Imports: creating a wrapper component for displaying SVGs.


This Vue 3 component below imports all files that

  • are located in /src/assets/svg folder, and
  • have .svg extension
// BaseSvg.vue

<template>
  <div v-html="svg" v-if="svg"></div>
</template>

<script lang="ts" setup>
import { computed } from "vue";

const props = defineProps<{
  name: string;
}>();

const modules = import.meta.glob("/src/assets/svg/*.svg", {
  query: "?raw",
  import: "default",
  eager: true,
});

const svg = computed(() => {
  return modules["/src/assets/svg/" + (props.name ?? "") + ".svg"] ?? null;
});
</script>

Enter fullscreen mode Exit fullscreen mode

Here's what we need to do when we add a new SVG to the project:

  1. Drop the file in the /svg folder
  2. Import the BaseSvg component and use it in the template
  3. Pass the filename we want to display, as the name prop.
// script
import BaseSvg from "@/components/BaseSvg.vue";

// template
<BaseSvg name="heart-icon" class="w-12 text-slate-500" />
Enter fullscreen mode Exit fullscreen mode

💡TIP: Set each svg file's width and height to "100%", and fill (or stroke) to "currentColor". This will help with adding styles to the component. Eg.:

// heart-icon.svg

<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 9.1371C2 14 6.01943 16.5914 8.96173 18.9109C10 19.7294 11 20.5 12 20.5C13 20.5 14 19.7294 15.0383 18.9109C17.9806 16.5914 22 14 22 9.1371C22 4.27416 16.4998 0.825464 12 5.50063C7.50016 0.825464 2 4.27416 2 9.1371Z" fill="currentColor"/>
</svg>
Enter fullscreen mode Exit fullscreen mode

So, there you have it. This wrapper component comes really handy in projects that use many custom icons. It helps DRYing up the code and keeping maintenance at a minimum.

Good luck, and have fun using it!

Top comments (0)