vue-fontawesome icon indicating copy to clipboard operation
vue-fontawesome copied to clipboard

Vue 3 support

Open Uninen opened this issue 5 years ago • 39 comments

Is your feature request related to a problem? Please describe. Vue 3 is already in late beta and some of the deeper APIs are incompatible with Vue 2. It would be nice to have a Vue 3 compatible fontawesome component.

Describe the solution you'd like Upgrade the component to use the new render APIs: https://github.com/vuejs/rfcs/pull/28

Uninen avatar May 24 '20 22:05 Uninen

I was wanting to use some font awesome icons in a project using vite, which uses vue 3. Since this doesn't yet support vue 3, I have been unable to do so (so far).

Vue 3 support would be greatly appreciated, and will be necessary when vue 3 is fully released.

redxtech avatar Jul 18 '20 00:07 redxtech

Vue 3 is now at release candidate stage, it would be good to have an update on this issue! From a quick look at the source it seems there is no quick workaround.

callumacrae avatar Jul 18 '20 16:07 callumacrae

I am getting this error:

TypeError: Cannot read property 'icon' of undefined

Not sure if it is related to Vue 3? I think it is, because it used to work with Vue 2.

I am using [email protected] and [email protected] with TypeScript.

pedzed avatar Jul 27 '20 22:07 pedzed

vue-fontawesome doesn’t currently support Vue 3, hence this ticket.

Uninen avatar Jul 27 '20 23:07 Uninen

Very frustrating. I am not even sure whether I should downgrade Vue or wait for a fix for vue-fontawesome.

@robmadole is there any ETA?

pedzed avatar Jul 27 '20 23:07 pedzed

@pedzed I've just been manually downloading the svgs and including them by hand, but that's not an acceptable fix now that vue 3 is in it's RC stage. Hopefully we get something soon.

redxtech avatar Jul 31 '20 19:07 redxtech

No answer, no ETA...

eduardoturconi avatar Aug 17 '20 19:08 eduardoturconi

Hi all! I've just created a component for Font Awesome which works with Vue 3. All you need to do is add this file as FontAwesomeIcon.vue inside a lib folder or something and import it as you would do with a normal Vue application.

Also, it's fully reactive, using Vue 3's new Composition API.

You still need to add your icons to the library

<template>
  <svg xmlns="http://www.w3.org/2000/svg" :class="$props.class" :viewBox="`0 0 ${width} ${height}`">
    <path fill="currentColor" :d="svgPath"/>
  </svg>
</template>

<script>
import { defineComponent, computed } from 'vue'
import { findIconDefinition } from '@fortawesome/fontawesome-svg-core'

export default defineComponent({
  name: 'FontAwesomeIcon',

  props: {
    icon: {
      type: String,
      required: true
    },
    class: String
  },

  setup (props) {
    const definition = computed(() => findIconDefinition({
      prefix: 'fas',
      iconName: props.icon
    }))

    const width = computed(() => definition.value.icon[0])
    const height = computed(() => definition.value.icon[1])
    const svgPath = computed(() => definition.value.icon[4])

    return { width, height, svgPath }
  }
})
</script>

midzdotdev avatar Sep 01 '20 10:09 midzdotdev

Just to clarify how I'm using this thing (where @ is the root of the Vue project)

  1. Make a file @/lib/FontAwesomeIcon.vue with the code above
  2. Make a file @/plugins/font-awesome.ts which configures the library, etc.
  3. Add this to your vue app in @/main.ts
// @/plugins/font-awesome.ts
import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import FontAwesomeIcon from '@/lib/FontAwesomeIcon.vue'

library.add(fas)

export {
  FontAwesomeIcon
}
// My @/main.ts
import { createApp } from 'vue'
import App from '@/App.vue'
import router from '@/router'
import { FontAwesomeIcon } from '@/plugins/font-awesome'

createApp(App)
  .use(router)
  .component('fa', FontAwesomeIcon)
  .mount('#app')

In my case, as I've registered the component globally as fa, I'll be able to use <fa :icon="iconName" class="..."></fa> in a Vue component to show the icon.

midzdotdev avatar Sep 01 '20 10:09 midzdotdev

I've just release @fortawesome/[email protected] thanks to the work from #246 and @rigma.

All: please give this pre-release a try and let me know what you think.

robmadole avatar Sep 01 '20 19:09 robmadole

I've just release @fortawesome/[email protected] thanks to the work from #246 and @rigma.

All: please give this pre-release a try and let me know what you think.

The README.md says to install with $ npm i --save @fortawesome/vue-fontawesome@3. However, it doesn't work, as it outputs this error:

npm ERR! code ETARGET
npm ERR! notarget No matching version found for @fortawesome/vue-fontawesome@3.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/raj/.npm/_logs/2020-09-04T02_35_55_060Z-debug.log

However, your instruction here to use the full version name does work: @fortawesome/[email protected]

Thought you may want to update the README.md (unless I'm making a silly mistake??)

rajsinghUSA avatar Sep 05 '20 02:09 rajsinghUSA

@james2mid Awesome ;-) Works great for displaying static icons (no support for sizing, transformations, ...). Thank you very much !

mon-compte-github avatar Sep 08 '20 07:09 mon-compte-github

yeah @rajsinghUSA right, I got the same error and I fixed with this : npm i --save @fortawesome/[email protected] I'm using Vue 3 with TypeScript, if anyone looking for a how-to integrate font awesome to their project, you can follow these steps :) (I improved @james2mid solution a little bit and I want to I wanted to put it all together)

1-) Firstly run these npm commands in your project's main folder;

$ npm i --save @fortawesome/fontawesome-svg-core
$ npm i --save @fortawesome/free-solid-svg-icons
$ npm i --save @fortawesome/free-brands-svg-icons
$ npm i --save @fortawesome/[email protected]

2-) Then create 'FontAwesomeIcon.vue' file with this content below under /libs path (you can create a folder in the main path)

<template>
  <svg
    xmlns="http://www.w3.org/2000/svg"
    :class="$props.class"
    :viewBox="`0 0 ${width} ${height}`"
  >
    <path fill="currentColor" :d="svgPath" />
  </svg>
</template>

<script>
import { defineComponent, computed } from "vue";
import { findIconDefinition } from "@fortawesome/fontawesome-svg-core";

export default defineComponent({
  name: "FontAwesomeIcon",

  props: {
    icon: {
      type: String,
      required: true
    },
    type: {
      type: String,
      default: "fas",
      required: false
    },
    class: String
  },

  setup(props) {
    const definition = computed(() =>
      findIconDefinition({
        prefix: props.type,
        iconName: props.icon
      })
    );

    const width = computed(() => definition.value.icon[0]);
    const height = computed(() => definition.value.icon[1]);
    const svgPath = computed(() => definition.value.icon[4]);

    return { width, height, svgPath };
  }
});
</script>

3-) Create 'font-awesome.ts' file with this content below under /plugins path (you can create a folder in the main path)

import { library } from "@fortawesome/fontawesome-svg-core";
import { fas } from "@fortawesome/free-solid-svg-icons";
import { faInstagram, faTwitter } from "@fortawesome/free-brands-svg-icons";
import FontAwesomeIcon from "@/libs/FontAwesomeIcon.vue";

library.add(fas, faTwitter, faInstagram);

export { FontAwesomeIcon };

4-) Finally register FontAwesome as a global component in main.ts file;

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import { FontAwesomeIcon } from "@/plugins/font-awesome";

createApp(App)
  .use(store)
  .use(router)
  .component("fa", FontAwesomeIcon)
  .mount("#app");

You can use like this:

Brand Logo Icon Example:

<fa icon="twitter" type="fab" class="classname"></fa>

Regular Icon Example:

<fa icon="align-right" class="classname"></fa>

I hope it helps everyone, especially for beginners like me :)

halilyuce avatar Sep 22 '20 13:09 halilyuce

The posted solution doesn't seem to work for duotone icons: Error: <path> attribute d: Expected path command, "…56.55 64 486 64z,M615.55 59.81c-…".

Livijn avatar Sep 26 '20 14:09 Livijn

The current package breaks Vue HMR

dipasqualew avatar Oct 06 '20 17:10 dipasqualew

Fixed thanks to @halilyuce with the first command, the repository indicate to enter this command to load Vue-3 fontawesome npm i --save @fortawesome/vue-fontawesome@3 However the right version command is the following : npm i --save @fortawesome/[email protected]

Rakedd avatar Oct 26 '20 20:10 Rakedd

@halilyuce solution didn't work for me. I'm getting a TypeError: cannot read propery 'icon' of undefined at the FontAwesomeIcon.vue component. it refers to the line const width = computed(() => definition.value.icon[0])

const definition = computed(() => findIconDefinition({ prefix: props.type, iconName: props.icon }) )

finIconDefinition is returning undefined, and when I looked at the definition in the @fortawesome/fontawesome-svg-core/index.d.ts it isn't defined, only it's type.

jvcmarcenes avatar Dec 22 '20 01:12 jvcmarcenes

createApp(App) .use(router) .component('fa', FontAwesomeIcon) .mount('#app')

My mistake was having the 'fa', FontAwesomeIcon in the use() instead of in the .component().

Eliaquim avatar Dec 31 '20 17:12 Eliaquim

I followed all the steps but I'm getting an error message : Cannot find module:"@/libs/FontAwesomeIcon.vue" or its corresponding type declaration. When I try to run my project I get the message : This dependency was not found: * @/plugins/font-awesome in ./src/main.js I'm then invited to run npm install --save @/plugins/font-awesome but getting a second error message telling me the token "@" is not recognized. I'm new to Vue (3), using Vue CLI, so I'm sure I'm doing something wrong or forgot something but can't figure out what...

Thanks for the help!

JStephens83 avatar Jan 07 '21 16:01 JStephens83

@jvcmarcenes In case you haven't solved your problem yet: I had the same issue. font-awesome.ts imports FontAwesomeIcon.vue from "@/libs/FontAwesomeIcon.vue" and main.ts imports FontAwesomeIcon from "@/plugins/font-awesome" - but my project didn't have @libs or @plugins setup. Once I changed the imports to their relative file paths, it all worked smoothly.

@JStephens83 you may be having a variant of the same issue,

JoshuaHull avatar Jan 11 '21 05:01 JoshuaHull

@JoshuaHull My imports were correct. My error was that in the FontAwesomeIcon.vue, the default for the 'type' props was set to 'fab', and I hand't installed the solid icons, only the regulars, so I changed the default to 'far' and now it works

jvcmarcenes avatar Jan 12 '21 16:01 jvcmarcenes

@JoshuaHull Unfortunately the issue does not come from here but really from the "@" which is not recognized, Still looking for what I did wrong. Wether I created the "libs" and "plugins" at the wrong place or forgot to install a specific dependency, I don't know yet.

JStephens83 avatar Jan 17 '21 10:01 JStephens83

@JoshuaHull when you say "my project didn't have @libs or @plugins setup." what do you mean exactly ? I tried using aliases in a vue.config.js file and I also tried using relative paths, but I still get the issue.

JStephens83 avatar Jan 17 '21 16:01 JStephens83

I've done so many tinkering (adding a tsconfig.json and a vue.config.js files and many other things) that I don't really know what fixed it but in the end it's now working. HOWEVER my "font-awesome.ts" file still has an inline error on the following import: import FontAwesomeIcon from "../libs/FontAwesomeIcon.vue"; The error message is : Cannot find module '../libs/FontAwesomeIcon.vue' or its corresponding type declarations. Which is weird....

JStephens83 avatar Jan 17 '21 21:01 JStephens83

I've done so many tinkering (adding a tsconfig.json and a vue.config.js files and many other things) that I don't really know what fixed it but in the end it's now working. HOWEVER my "font-awesome.ts" file still has an inline error on the following import: import FontAwesomeIcon from "../libs/FontAwesomeIcon.vue"; The error message is : Cannot find module '../libs/FontAwesomeIcon.vue' or its corresponding type declarations. Which is weird....

And you made the libs folder with the FontAwesomeIcone.vue code?

khari998 avatar Jan 21 '21 00:01 khari998

I've done so many tinkering (adding a tsconfig.json and a vue.config.js files and many other things) that I don't really know what fixed it but in the end it's now working. HOWEVER my "font-awesome.ts" file still has an inline error on the following import: import FontAwesomeIcon from "../libs/FontAwesomeIcon.vue"; The error message is : Cannot find module '../libs/FontAwesomeIcon.vue' or its corresponding type declarations. Which is weird....

And you made the libs folder with the FontAwesomeIcone.vue code?

Yes I manually created the folder and added FontAwesomeIcon.vue in it

JStephens83 avatar Jan 21 '21 00:01 JStephens83

@JStephens83 This is what I have and it's working for me. I changed my folder name from libs to lib but that shouldn't matter. I had to restart my server once they were created.

font-awesome.ts

import { library } from "@fortawesome/fontawesome-svg-core";
import { fas, faTimes } from "@fortawesome/free-solid-svg-icons";
import { far, faWindowClose } from "@fortawesome/free-regular-svg-icons";
import FontAwesomeIcon from "../lib/FontAwesomeIcon.vue";
import {
  faFacebookF,
  faLinkedinIn,
  faTwitter,
  faInstagram
} from "@fortawesome/free-brands-svg-icons";

library.add(
  fas,
  far,
  faWindowClose,
  faFacebookF,
  faLinkedinIn,
  faTwitter,
  faInstagram,
  faTimes,
  faWindowClose
);

export { FontAwesomeIcon };

FontAwesome.vue

<template>
  <svg
    xmlns="http://www.w3.org/2000/svg"
    :class="$props.class"
    :viewBox="`0 0 ${width} ${height}`"
  >
    <path fill="currentColor" :d="svgPath" />
  </svg>
</template>

<script>
import { defineComponent, computed } from "vue";
import { findIconDefinition } from "@fortawesome/fontawesome-svg-core";

export default defineComponent({
  name: "FontAwesomeIcon",

  props: {
    icon: {
      type: String,
      required: true
    },
    type: {
      type: String,
      default: "fas",
      required: false
    },
    class: String
  },

  setup(props) {
    const definition = computed(() =>
      findIconDefinition({
        prefix: props.type,
        iconName: props.icon
      })
    );

    const width = computed(() => definition.value.icon[0]);
    const height = computed(() => definition.value.icon[1]);
    const svgPath = computed(() => definition.value.icon[4]);

    return { width, height, svgPath };
  }
});
</script>

project structure :

src/
-- plugins/
---- font-awesome.ts
-- lib/
---- FontAwesomeIcon.vue

khari998 avatar Jan 21 '21 00:01 khari998

in the newest prerelease install there seems to be a vue component included already, works great

MrBrax avatar Jan 21 '21 00:01 MrBrax

@kamaslau Yes I have the exact same organization and content. It's working fine, my only issue now is that VSCode shows an inline error on import FontAwesomeIcon from "../lib/FontAwesomeIcon.vue"; and I don't know why. Thanks for sharing!

JStephens83 avatar Jan 21 '21 16:01 JStephens83

yarn add @fortawesome/fontawesome-svg-core
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/free-brands-svg-icons
yarn add @fortawesome/free-regular-svg-icons
import { faGithub } from '@fortawesome/free-brands-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { faPlay } from '@fortawesome/free-solid-svg-icons'
library.add(faGithub, faPlay);

createApp(App).component("fa", FontAwesomeIcon).mount("#app");

<fa icon="github"></fa>

MrBrax avatar Jan 22 '21 15:01 MrBrax