How to import custom svg icons in vuetify 3?
Asked Answered
A

4

9

How to import custom svg icons in vuetify3 and nuxt3?

In vuetify 2, we were able to directly import svg icons like this

import customIcon from './myIcon.vue'
Vue.use(Vuetify)
export default new Vuetify({
  icons: {
    iconfont: 'mdi',
    values: {
      myIcon: {component: customIcon}
    },
  },
})

---------------

// Used like this in vue file
<v-icon>$myIcon</v-icon>

From veutfiy 3 documentation, I am confused about importing custom svg icons as it is using sets instead of values. https://next.vuetifyjs.com/en/features/icon-fonts/

// plugins/vuetify.js
import { createVuetify } from "vuetify";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";
import { aliases, mdi } from "vuetify/iconsets/mdi";
export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    components,
    directives,
    icons: {
      defaultSet: "mdi",
      aliases,
      sets: {
        mdi,
      },
    },
  });
  nuxtApp.vueApp.use(vuetify);
});

Adelleadelpho answered 21/9, 2022 at 5:28 Comment(3)
welcome. Do you get any error in console or just wanna figure it out better?Asyllabic
Sort of yes. When I try to add custom icons then mdi icons don't work. I want to use both mdi and custom svg iconsAdelleadelpho
Please post up yr error consoleAsyllabic
A
18

Found a way to use both mdi and custom svg icons

Icon file

//tickicon.vue
<template>
<svg>... icon here</svg>
<template>

//customSvgs.ts
import { h } from "vue";
import type { IconSet, IconProps } from "vuetify";
import tickIcon from "./customSVGs/tickicon.vue";
import closeIcon from "./customSVGs/close-icon.vue";

const customSvgNameToComponent: any = {
  tickIcon,
  closeIcon,
};

const customSVGs: IconSet = {
  component: (props: IconProps) => h(customSvgNameToComponent[props.icon]),
};

export { customSVGs /* aliases */ };

And my vuetify plugin file


// plugins/vuetify.ts
import { createVuetify } from "vuetify";
import { mdi } from "vuetify/iconsets/mdi";
import { customSVGs } from "~~/assets/customSVGs";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    components,
    directives,
    icons: {
      defaultSet: "mdi",
      sets: {
        mdi,
        custom: customSVGs,
      },
    },
  });

  nuxtApp.vueApp.use(vuetify);
});


Using like that in vue file

<v-icon icon="custom:tickIcon"/> //Custom SVG Icon 
<v-icon icon="mdi-arrow-up"/>  //default mdi icon
Adelleadelpho answered 4/10, 2022 at 2:45 Comment(0)
M
7

Complement the answer of @rookie-coder

To get the correct vuetify v-icon style, you need to wrap the svg icon in a tag <i> and give the class v-icon__svg to the <svg> element.

const custom: IconSet = {
  component: (props: IconProps) =>
    h(props.tag, [h(customSvgNameToComponent[props.icon as string], { class: 'v-icon__svg' })]),
}

const vuetify = createVuetify({
  icons: {
    defaultSet: "mdi",
    sets: {
      mdi,
      custom,
    },
  },
});
Monied answered 10/3, 2023 at 10:26 Comment(1)
to apply color to the icon remove all fill tags, to apply the size remove width and height of the svgHomocyclic
S
0

Setup is same as my project, Did you include the actual icons at the top of vuetify.js?

import '@mdi/font/css/materialdesignicons.css'

Is the only thing I see missing from what you posted.

Snatchy answered 28/9, 2022 at 23:32 Comment(0)
C
0

If you use Vuetify 3 + Nuxt 3, and need to use a customized library such as nuxt-icon or iconify injected in v-icon, you can create a custom component to provide the inject with all heritage styles direct from v-icon.

1- Create a new component (in this exemple I'll use nuxt-icon: ~/components/MyIcon.vue

<template>
  <div>
    <Icon :name="name" :size="1em" />
    <!-- size as 1em will return the size of the inherited v-icon 
         as well as the color -->
  </div>
</template>

<script setup lang="ts">
defineProps({
  name: {
    type: String,
    required: true,
    default: "",
  },
});
</script>

2- Create a new render IconSet from Vuetify: ~/components/MyIconRender.ts

import { h } from "vue";
import type { IconSet, IconProps } from "vuetify";
import MyIcon from "~~/components/MyIcon.vue";

const Icon: IconSet = {
  component: (props: IconProps) => {
    return h(MyIcon, {
      name: props.icon as string
    });
  },
};

export { MyIcon };

3- Configure Vuetify to use MyIcon as default: ~/plugins/vuetify.ts

import { createVuetify } from "vuetify";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";
import { MyIcon } from "~/components/MyIconRender";

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    ssr: true,
    components,
    directives,
    icons: {
      defaultSet: "custom",
      sets: {
        custom: MyIcon,
      },
    },
  });
  nuxtApp.vueApp.use(vuetify);
});

So in this way you can use any icon library injected direct in Vuetify 3. The best thing about this implementation is that all Vuetify 3 classes will work, for example: color: primary, or class pa-5, etc.

Charteris answered 29/3, 2023 at 16:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.