vue-fontawesome
vue-fontawesome copied to clipboard
Vue 3 support
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
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.
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.
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.
vue-fontawesome doesn’t currently support Vue 3, hence this ticket.
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 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.
No answer, no ETA...
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>
Just to clarify how I'm using this thing (where @ is the root of the Vue project)
- Make a file
@/lib/FontAwesomeIcon.vuewith the code above - Make a file
@/plugins/font-awesome.tswhich configures the library, etc. - 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.
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.
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??)
@james2mid Awesome ;-) Works great for displaying static icons (no support for sizing, transformations, ...). Thank you very much !
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 :)
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-…".
The current package breaks Vue HMR
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]
@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.
createApp(App) .use(router) .component('fa', FontAwesomeIcon) .mount('#app')
My mistake was having the 'fa', FontAwesomeIcon in the use() instead of in the .component().
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!
@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 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
@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.
@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.
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....
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?
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 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
in the newest prerelease install there seems to be a vue component included already, works great
@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!
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>