How to use Fluent UI System Icons in Vue and Nuxt
By Colton Griffith · Updated
Microsoft maintains an official React package for Fluent UI System Icons, but not a Vue one. That's not a problem. The icons are simple, single-color SVGs, so there are several clean ways to use them in Vue 3 and Nuxt. This guide covers three, from zero dependencies to fully automatic.
Option 1: copy the icon as a Vue component
For a few icons, this is the simplest approach. Open an icon on Fluenticons, choose Vue Component in the copy menu, and paste it into a new file:
<!-- components/icons/Delete24Regular.vue -->
<template>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="…" fill="currentColor" />
</svg>
</template>
Make sure the path uses fill="currentColor". When you copy from the editor, pick the color you want, or edit the fill afterwards. Then the icon inherits the text color wherever you use it:
<button class="text-red-600">
<Delete24Regular class="h-5 w-5" />
Delete
</button>
Vue passes class and other attributes through to the root <svg>, so sizing with CSS classes works without extra props.
Good for: small projects, design systems where you want full control over the markup.
Option 2: import SVG files with vite-svg-loader
If you'd rather keep the original .svg files in your repo, vite-svg-loader turns them into Vue components at build time.
npm install -D vite-svg-loader
// vite.config.js
import vue from "@vitejs/plugin-vue";
import svgLoader from "vite-svg-loader";
export default {
plugins: [vue(), svgLoader()],
};
Download the SVG from any icon page and import it:
<script setup>
import DeleteIcon from "@/assets/icons/ic_fluent_delete_24_regular.svg?component";
</script>
<template>
<DeleteIcon class="h-5 w-5" aria-hidden="true" />
</template>
The downloaded files use a fixed dark gray fill (#212121). Replace it with currentColor once so the icons follow your text color. A quick find-and-replace across your icons folder does it.
Good for: teams that want the original files under version control.
Option 3: on-demand icons with unplugin-icons
unplugin-icons can import any icon from the Iconify collections as a component, and only the icons you use end up in your bundle. Iconify includes the Fluent UI System Icons under the fluent prefix.
npm install -D unplugin-icons @iconify-json/fluent
// vite.config.js
import vue from "@vitejs/plugin-vue";
import Icons from "unplugin-icons/vite";
export default {
plugins: [vue(), Icons({ compiler: "vue3" })],
};
Icon names are the icon name in kebab-case, then the size and style:
<script setup>
import DeleteRegular from "~icons/fluent/delete-24-regular";
import HeartFilled from "~icons/fluent/heart-24-filled";
</script>
<template>
<DeleteRegular />
<HeartFilled class="text-rose-600" />
</template>
In Nuxt, add the plugin through vite.plugins in nuxt.config, or use a Nuxt icon module that supports Iconify collections.
Good for: larger apps that use many icons and want automatic tree-shaking.
Toggling between filled and regular
For state toggles such as favorites, likes or selected tabs, render one or the other:
<template>
<button type="button" :aria-pressed="isFavorite" @click="isFavorite = !isFavorite">
<HeartFilled v-if="isFavorite" />
<HeartRegular v-else />
Favorite
</button>
</template>
Both styles share the same grid and outer shape, so swapping them doesn't shift the layout.
Accessibility
- If the icon sits next to visible text, add
aria-hidden="true"to the SVG so screen readers skip it. - If the button has only an icon, put
aria-labelon the button, not the SVG. - Don't rely on color alone to communicate state. Pair it with the filled/regular change or with text.
Which option should you choose?
| Copied components | vite-svg-loader | unplugin-icons | |
|---|---|---|---|
| Dependencies | None | 1 dev dependency | 2 dev dependencies |
| Adding a new icon | Copy and paste | Download the file | Change the import |
| Tree-shaking | Manual | Automatic | Automatic |
| Works without a build step | Yes | No | No |
If you're unsure, start with option 1 and move to option 3 once you're using more than a dozen or so icons.
Find the icons mentioned here with the icon search, or read another guide.