[{"data":1,"prerenderedAt":10},["ShallowReactive",2],{"guide-use-fluent-icons-in-vue":3},{"slug":4,"title":5,"description":6,"date":7,"order":8,"html":9},"use-fluent-icons-in-vue","How to use Fluent UI System Icons in Vue and Nuxt","Three ways to use Fluent icons in Vue 3 and Nuxt — copied SVG components, SVG files with vite-svg-loader, and on-demand icons with unplugin-icons and Iconify.","2026-09-23",2,"\u003Cp>Microsoft maintains an official React package for Fluent UI System Icons, but not a Vue one. That&#39;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.\u003C\u002Fp>\n\u003Ch2>Option 1: copy the icon as a Vue component\u003C\u002Fh2>\n\u003Cp>For a few icons, this is the simplest approach. Open an icon on Fluenticons, choose \u003Cstrong>Vue Component\u003C\u002Fstrong> in the copy menu, and paste it into a new file:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-vue\">&lt;!-- components\u002Ficons\u002FDelete24Regular.vue --&gt;\n&lt;template&gt;\n  &lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; xmlns=&quot;http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg&quot;&gt;\n    &lt;path d=&quot;…&quot; fill=&quot;currentColor&quot; \u002F&gt;\n  &lt;\u002Fsvg&gt;\n&lt;\u002Ftemplate&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Make sure the path uses \u003Ccode>fill=&quot;currentColor&quot;\u003C\u002Fcode>. 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:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-vue\">&lt;button class=&quot;text-red-600&quot;&gt;\n  &lt;Delete24Regular class=&quot;h-5 w-5&quot; \u002F&gt;\n  Delete\n&lt;\u002Fbutton&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Vue passes \u003Ccode>class\u003C\u002Fcode> and other attributes through to the root \u003Ccode>&lt;svg&gt;\u003C\u002Fcode>, so sizing with CSS classes works without extra props.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Good for:\u003C\u002Fstrong> small projects, design systems where you want full control over the markup.\u003C\u002Fp>\n\u003Ch2>Option 2: import SVG files with vite-svg-loader\u003C\u002Fh2>\n\u003Cp>If you&#39;d rather keep the original \u003Ccode>.svg\u003C\u002Fcode> files in your repo, \u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fvite-svg-loader\">\u003Ccode>vite-svg-loader\u003C\u002Fcode>\u003C\u002Fa> turns them into Vue components at build time.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">npm install -D vite-svg-loader\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cpre>\u003Ccode class=\"language-js\">\u002F\u002F vite.config.js\nimport vue from &quot;@vitejs\u002Fplugin-vue&quot;;\nimport svgLoader from &quot;vite-svg-loader&quot;;\n\nexport default {\n  plugins: [vue(), svgLoader()],\n};\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Download the SVG from any icon page and import it:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-vue\">&lt;script setup&gt;\nimport DeleteIcon from &quot;@\u002Fassets\u002Ficons\u002Fic_fluent_delete_24_regular.svg?component&quot;;\n&lt;\u002Fscript&gt;\n\n&lt;template&gt;\n  &lt;DeleteIcon class=&quot;h-5 w-5&quot; aria-hidden=&quot;true&quot; \u002F&gt;\n&lt;\u002Ftemplate&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The downloaded files use a fixed dark gray fill (\u003Ccode>#212121\u003C\u002Fcode>). Replace it with \u003Ccode>currentColor\u003C\u002Fcode> once so the icons follow your text color. A quick find-and-replace across your icons folder does it.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Good for:\u003C\u002Fstrong> teams that want the original files under version control.\u003C\u002Fp>\n\u003Ch2>Option 3: on-demand icons with unplugin-icons\u003C\u002Fh2>\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Funplugin-icons\">\u003Ccode>unplugin-icons\u003C\u002Fcode>\u003C\u002Fa> can import any icon from the \u003Ca href=\"https:\u002F\u002Ficonify.design\">Iconify\u003C\u002Fa> collections as a component, and only the icons you use end up in your bundle. Iconify includes the Fluent UI System Icons under the \u003Ccode>fluent\u003C\u002Fcode> prefix.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">npm install -D unplugin-icons @iconify-json\u002Ffluent\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cpre>\u003Ccode class=\"language-js\">\u002F\u002F vite.config.js\nimport vue from &quot;@vitejs\u002Fplugin-vue&quot;;\nimport Icons from &quot;unplugin-icons\u002Fvite&quot;;\n\nexport default {\n  plugins: [vue(), Icons({ compiler: &quot;vue3&quot; })],\n};\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Icon names are the icon name in kebab-case, then the size and style:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-vue\">&lt;script setup&gt;\nimport DeleteRegular from &quot;~icons\u002Ffluent\u002Fdelete-24-regular&quot;;\nimport HeartFilled from &quot;~icons\u002Ffluent\u002Fheart-24-filled&quot;;\n&lt;\u002Fscript&gt;\n\n&lt;template&gt;\n  &lt;DeleteRegular \u002F&gt;\n  &lt;HeartFilled class=&quot;text-rose-600&quot; \u002F&gt;\n&lt;\u002Ftemplate&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>In \u003Cstrong>Nuxt\u003C\u002Fstrong>, add the plugin through \u003Ccode>vite.plugins\u003C\u002Fcode> in \u003Ccode>nuxt.config\u003C\u002Fcode>, or use a Nuxt icon module that supports Iconify collections.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Good for:\u003C\u002Fstrong> larger apps that use many icons and want automatic tree-shaking.\u003C\u002Fp>\n\u003Ch2>Toggling between filled and regular\u003C\u002Fh2>\n\u003Cp>For state toggles such as favorites, likes or selected tabs, render one or the other:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-vue\">&lt;template&gt;\n  &lt;button type=&quot;button&quot; :aria-pressed=&quot;isFavorite&quot; @click=&quot;isFavorite = !isFavorite&quot;&gt;\n    &lt;HeartFilled v-if=&quot;isFavorite&quot; \u002F&gt;\n    &lt;HeartRegular v-else \u002F&gt;\n    Favorite\n  &lt;\u002Fbutton&gt;\n&lt;\u002Ftemplate&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Both styles share the same grid and outer shape, so swapping them doesn&#39;t shift the layout.\u003C\u002Fp>\n\u003Ch2>Accessibility\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>If the icon sits next to visible text, add \u003Ccode>aria-hidden=&quot;true&quot;\u003C\u002Fcode> to the SVG so screen readers skip it.\u003C\u002Fli>\n\u003Cli>If the button has only an icon, put \u003Ccode>aria-label\u003C\u002Fcode> on the \u003Cstrong>button\u003C\u002Fstrong>, not the SVG.\u003C\u002Fli>\n\u003Cli>Don&#39;t rely on color alone to communicate state. Pair it with the filled\u002Fregular change or with text.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Which option should you choose?\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>\u003C\u002Fth>\n\u003Cth>Copied components\u003C\u002Fth>\n\u003Cth>vite-svg-loader\u003C\u002Fth>\n\u003Cth>unplugin-icons\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>Dependencies\u003C\u002Ftd>\n\u003Ctd>None\u003C\u002Ftd>\n\u003Ctd>1 dev dependency\u003C\u002Ftd>\n\u003Ctd>2 dev dependencies\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Adding a new icon\u003C\u002Ftd>\n\u003Ctd>Copy and paste\u003C\u002Ftd>\n\u003Ctd>Download the file\u003C\u002Ftd>\n\u003Ctd>Change the import\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Tree-shaking\u003C\u002Ftd>\n\u003Ctd>Manual\u003C\u002Ftd>\n\u003Ctd>Automatic\u003C\u002Ftd>\n\u003Ctd>Automatic\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Works without a build step\u003C\u002Ftd>\n\u003Ctd>Yes\u003C\u002Ftd>\n\u003Ctd>No\u003C\u002Ftd>\n\u003Ctd>No\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>If you&#39;re unsure, start with option 1 and move to option 3 once you&#39;re using more than a dozen or so icons.\u003C\u002Fp>\n",1790215639582]