Vue Material Design Icons
vue-material-design-icons provides a comprehensive collection of Material Design Icons encapsulated as Vue single-file components, enabling seamless integration into Vue.js projects. The library is currently stable at version 5.3.1 and maintains an active release cadence, frequently updating its icon set to mirror the upstream MaterialDesign project. A key differentiator is its packaging of each icon as an individual Vue component, allowing for granular imports and optimized bundle sizes. It supports both Vue 2 and Vue 3, with a significant breaking change in version 5.0.0 to introduce Vue 3 compatibility while ensuring continued support for Vue 2 applications. The package also offers an optional stylesheet for easier scaling and various props for customization like `fillColor` and `size`, along with important accessibility considerations for screen readers.
Common errors
-
[Vue warn]: Failed to resolve component: <IconName>. If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
cause The icon component was imported but not correctly registered in the Vue component's `components` option, or the import path/name was incorrect.fixEnsure `import MyIcon from 'vue-material-design-icons/MyIcon.vue';` is correct, and then `components: { MyIcon }` is added to your Vue component definition. -
ERROR in ./node_modules/vue-material-design-icons/Menu.vue Module not found: Error: Can't resolve './Menu.vue' in '...'
cause Incorrect import path, missing `.vue` extension, or wrong casing for the icon file.fixVerify the icon file name (PascalCase) and ensure the `.vue` extension is included in the import statement, e.g., `import MenuIcon from 'vue-material-design-icons/Menu.vue';`. -
Icon appears but doesn't scale with text or has an unexpected color.
cause The `size` or `fillColor` prop is conflicting with styles from `vue-material-design-icons/styles.css` or custom CSS.fixReview your CSS rules and prop usage. If using `styles.css`, consider defining icon sizes and colors primarily via CSS classes, or ensure prop values override CSS as intended. Avoid conflicting approaches. -
Screen readers ignore the icon or read its name verbatim, without context.
cause The `title` prop was omitted or provided with a non-descriptive value, leading the icon to be `aria-hidden` or announced poorly.fixProvide a descriptive `title` prop for the icon when it conveys meaning, e.g., `<MenuIcon title="Open navigation menu" />`. If the icon is purely decorative, no `title` is needed, but be aware it won't be announced.
Warnings
- breaking Version 5.0.0 introduced Vue 3 compatibility but reverted previous changes that made components functional, potentially leading to minor performance regressions on pages with a high density of icons compared to earlier functional component implementations.
- gotcha For accessibility, icons are hidden from screen readers (`aria-hidden="true"`) by default if no `title` prop is provided. This forces developers to consider the icon's purpose. Provide a descriptive `title` for meaningful icons, or ensure purely decorative icons are correctly handled by assistive technologies.
- gotcha The optional `styles.css` file includes CSS rules (e.g., `fill: currentColor;`) that might conflict with or override colors and sizes set via the `fillColor` or `size` props. If you import the stylesheet, CSS rules may take precedence.
- gotcha Icon names from the Material Design Icons website (which often use kebab-case like `ultra-high-definition`) must be converted to PascalCase (e.g., `UltraHighDefinition.vue`) and include the `.vue` extension for imports.
- bug Prior to version 5.3.1, the `aria-hidden` attribute was set with a boolean value, which could be misinterpreted by browsers or accessibility tools expecting a string ('true' or 'false'). This was fixed to ensure correct string value usage.
Install
-
npm install vue-material-design-icons -
yarn add vue-material-design-icons -
pnpm add vue-material-design-icons
Imports
- MenuIcon
const MenuIcon = require('vue-material-design-icons/Menu.vue');import MenuIcon from 'vue-material-design-icons/Menu.vue';
- styles.css
const styles = require('vue-material-design-icons/styles.css');import 'vue-material-design-icons/styles.css';
- AndroidIcon
import { AndroidIcon } from 'vue-material-design-icons/Android.vue';import AndroidIcon from 'vue-material-design-icons/Android.vue';
Quickstart
<!-- App.vue -->
<template>
<div id="app">
<h1>My Vue App with Material Icons</h1>
<p>
Here's a menu icon: <MenuIcon :size="32" fillColor="blue" title="Open Navigation" />
</p>
<p>
And an Android icon: <AndroidIcon title="Android Application" />
</p>
<p>
A larger, red home icon: <HomeIcon :size="48" fillColor="red" title="Go to homepage" />
</p>
<p>
A purely decorative icon: <LightbulbOnOutlineIcon />
</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import MenuIcon from 'vue-material-design-icons/Menu.vue';
import AndroidIcon from 'vue-material-design-icons/Android.vue';
import HomeIcon from 'vue-material-design-icons/Home.vue';
import LightbulbOnOutlineIcon from 'vue-material-design-icons/LightbulbOnOutline.vue';
export default defineComponent({
name: 'App',
components: {
MenuIcon,
AndroidIcon,
HomeIcon,
LightbulbOnOutlineIcon
},
});
</script>
<style>
/* main.css or global styles */
@import 'vue-material-design-icons/styles.css'; /* Optional: for default scaling */
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>