Icon don't show up with vuetify/mdi - vue.js

I want to use an Icon library and because it could be advantageous for other things, I decided to just use Vuetify, as it includes other design advantages than just the ability to include Icons.
After installing #mdi/js and Vuetify with npm in my existing project, I have the following code in my src/plugins/vuetify.ts folder:
import "vuetify/styles";
import { createVuetify } from "vuetify";
import { aliases, mdi } from "vuetify/iconsets/mdi"
export default createVuetify({
icons: {
defaultSet: "mdi",
aliases,
sets: {
mdi,
},
},
});
Now to insert icons, it is recommended to use #mdi/js because as I understand it only the actual used Icons will be imported.
This is how my App.vue looks like:
<script setup lang="ts">
import { mdiAccount } from '#mdi/js';
</script>
<template>
<main>
<v-icon :icon="mdiAccount" size="16" color="white" class="h-25 w-25"/>
</main>
</template>
So pretty much the example given in the Documentation, just with the composition api (unless I made a mistake)...
Can you spot the mistake I made?

You can use the answer here to get some universal icons: https://stackoverflow.com/a/72055404/8816585
If you also care about the types, you can use the following in tsconfig.json
"compilerOptions": {
"types": [
"unplugin-icons/types/vue",
]
}

Related

Vuetify 3: Use Svg as a v-icon

I would like to use my custom svg as a v-icon but I don't find any solutions in the Vuetify v3 documentation.
In the vuetify v2, I can do this kind of things in my vuetify.js:
export default new Vuetify({
icons:{
values: {
test: {
component: Test,
},
And I can use this like this:
<v-icon size="40">$vuetify.icons.test</v-icon>
How I can do the same thing in Vuetify v3 ? Thanks for your help :)
Below code shows an example of adding a custom icon along with the mdi set of icons to Vuetify and using both in a component via aliases.
vuetify.js
import { createVuetify } from 'vuetify'
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg'
import folder from '#/customIcons/folderIcon.vue'
const aliasesCustom = {
...aliases,
folder,
}
export const vuetify = createVuetify({
icons: {
defaultSet: 'mdi',
aliases: {
...aliasesCustom
},
sets: {
mdi,
},
},
})
folderIcon.vue (your custom icon)
<template>
<svg>...</svg>
</template>
any SFC
<template>
<v-icon>$folder</v-icon>
<v-icon>$mdiGithub</v-icon>
</template>
Original source: this thread in the Vuetify discord channel

How to use Swiper.js(version 8+) in Nuxt(2.15.8)

First I tried this as showed in official Swiper.js website for Vue 3 demo
<template>
<swiper
:effect="'coverflow'"
:grabCursor="true"
:centeredSlides="true"
:slidesPerView="'auto'"
:coverflowEffect="{
rotate: 50,
stretch: 0,
depth: 100,
modifier: 1,
slideShadows: true,
}"
:pagination="true"
:modules="modules"
class="mySwiper"
>
<swiper-slide v-for="card in cards"
><img
:src="card.image" /></swiper-slide>
</swiper>
</template>
<script>
// Import Swiper Vue.js components
import { Swiper, SwiperSlide } from "swiper/vue";
// Import Swiper styles
import "swiper/css";
import "swiper/css/effect-coverflow";
import "swiper/css/pagination";
import "./style.css";
// import required modules
import { EffectCoverflow, Pagination } from "swiper";
export default {
props: ['cards']
setup() {
return {
modules: [EffectCoverflow, Pagination],
};
},
};
</script>
And it did not work.
Then I tried to import it as a plugin in plugins folder of nuxt:
import Vue from 'vue';
import { Swiper, EffectCoverflow, Pagination } from "swiper";
const swiper = {
install(Vue, options) {
Vue.prototype.$swiper = Swiper;
Vue.prototype.$swiperModules = {
EffectCoverflow,
Pagination,
};
}
};
Vue.use(swiper);
And registred it in nuxt.js.config as: src: './plugins/swiper.client.js', mode: 'client'
And tried to use it in my component like this:
<template>
<Swiper>
<SwiperSlide v-for="card in cards" :key="card.id">
<NuxtLink :to="`products/${card.id}`" class="card">
<img
:src="require(card.image)"
alt="image"
class="image"
/>
<h3 class="header">{{ card.title }}</h3>
<p class="snippet">{{ card.snippet }}</p>
</NuxtLink>
</SwiperSlide>
</Swiper>
</template>
<script>
export default {
props: ['cards'],
mounted() {
this.swiper = new this.$swiper('.swiper', {
loop: true,
// configure Swiper to use modules
modules: [
this.$swiperModules.Pagination,
this.$swiperModules.EffectCoverflow,
],
})
},
}
</script>
And it is still not working, What am I doing wrong?
Can anyone help with it?
TLDR: Nuxt2 and Swiper8 are not compatible.
Swiper v8.0.0 is almost 1 year old: https://github.com/nolimits4web/swiper/releases/tag/v8.0.0
2 years ago, nolimits4web aka the main maintainer of the package said
Swiper Vue.js components are compatible only with new Vue.js version 3
Easy to say that the v8 of Swiper is definitely not compatible with Nuxt2 (using Vue2).
Even if there was a hack, it would be quite dirty and not the thing that I would recommend overall.
swiper#8.4.5 is also 38.7kB gzipped, which is quite on the heavy side of things.
If you're using all of its features and ready to upgrade to Nuxt3 (which might not be trivial), then you could maybe proceed.
Otherwise, you could maybe design your own carousel component or check the ones available here: https://github.com/vuejs/awesome-vue#carousel
I'm guessing that there are some projects with Nuxt2 support still, not too heavy and still maintained that could satisfy your needs.

Why is my `client-only` component in nuxt complaining that `window is not defined`?

I have Vue SPA that I'm trying to migrate to nuxt. I am using vue2leaflet in a component that I enclosed in <client-only> tags but still getting an error from nuxt saying that window is not defined.
I know I could use nuxt-leaflet or create a plugin but that increases the vendor bundle dramatically and I don't want that. I want to import the leaflet plugin only for the components that need it. Any way to do this?
<client-only>
<map></map>
</client-only>
And the map component:
<template>
<div id="map-container">
<l-map
style="height: 80%; width: 100%"
:zoom="zoom"
:center="center"
#update:zoom="zoomUpdated"
#update:center="centerUpdated"
#update:bounds="boundsUpdated"
>
<l-tile-layer :url="url"></l-tile-layer>
</l-map>
</div>
</template>
<script>
import {
LMap,
LTileLayer,
LMarker,
LFeatureGroup,
LGeoJson,
LPolyline,
LPolygon,
LControlScale
} from 'vue2-leaflet';
import { Icon } from 'leaflet';
import 'leaflet/dist/leaflet.css';
// this part resolve an issue where the markers would not appear
delete Icon.Default.prototype._getIconUrl;
export default {
name: 'map',
components: {
LMap,
LTileLayer,
LMarker,
LFeatureGroup,
LGeoJson,
LPolyline,
LPolygon,
LControlScale
},
//...
I found a way that works though I'm not sure how. In the parent component, you move the import statement inside component declarations.
<template>
<client-only>
<map/>
</client-only>
</template>
<script>
export default {
name: 'parent-component',
components: {
Map: () => if(process.client){return import('../components/Map.vue')},
},
}
</script>
<template>
<client-only>
<map/>
</client-only>
</template>
<script>
export default {
name: 'parent-component',
components: {
Map: () =>
if (process.client) {
return import ('../components/Map.vue')
},
},
}
</script>
The solutions above did not work for me.
Why? This took me a while to find out so I hope it helps someone else.
The "problem" is that Nuxt automatically includes Components from the "components" folder so you don't have to include them manually. This means that even if you load it dynamically only on process.client it will still load it server side due to this automatism.
I have found the following two solutions:
Rename the "components" folder to something else to stop the automatic import and then use the solution above (process.client).
(and better option IMO) there is yet another feature to lazy load the automatically loaded components. To do this prefix the component name with "lazy-". This, in combination with will prevent the component from being rendered server-side.
In the end your setup should look like this
Files:
./components/map.vue
./pages/index.html
index.html:
<template>
<client-only>
<lazy-map/>
</client-only>
</template>
<script>
export default {
}
</script>
The <client-only> component doesn’t do what you think it does. Yes, it skips rendering your component on the server side, but it still gets executed!
https://deltener.com/blog/common-problems-with-the-nuxt-client-only-component/
Answers here are more focused towards import the Map.vue component while the best approach is probably to properly load the leaflet package initially inside of Map.vue.
Here, the best solution would be to load the components like so in Map.vue
<template>
<div id="map-container">
<l-map style="height: 80%; width: 100%">
<l-tile-layer :url="url"></l-tile-layer>
</l-map>
</div>
</template>
<script>
import 'leaflet/dist/leaflet.css'
export default {
name: 'Map',
components: {
[process.client && 'LMap']: () => import('vue2-leaflet').LMap,
[process.client && 'LTileLayer']: () => import('vue2-leaflet').LTileLayer,
},
}
</script>
I'm not a leaflet expert, hence I'm not sure if Leaflet care if you import it like import('vue2-leaflet').LMap but looking at this issue, it looks like it doesn't change a lot performance-wise.
Using Nuxt plugins is NOT a good idea as explained by OP because it will increase the whole bundle size upfront. Meaning that it will increase the loading time of your whole application while the Map is being used only in one place.
My How to fix navigator / window / document is undefined in Nuxt answer goes a bit more in detail about this topic and alternative approaches to solve this kind of issues.
Especially if you want to import a single library like vue2-editor, jsplumb or alike.
Here is how I do it with Nuxt in Universal mode:
this will: 1. Work with SSR
2. Throw no errors related to missing marker-images/shadow
3. Make sure leaflet is loaded only where it's needed (meaning no plugin is needed)
4. Allow for custom icon settings etc
5. Allow for some plugins (they were a pain, for some reason I thought you could just add them as plugins.. turns out adding them to plugins would defeat the local import of leaflet and force it to be bundled with vendors.js)
Wrap your template in <client-only></client-only>
<script>
let LMap, LTileLayer, LMarker, LPopup, LIcon, LControlAttribution, LControlZoom, Vue2LeafletMarkerCluster, Icon
if (process.client) {
require("leaflet");
({
LMap,
LTileLayer,
LMarker,
LPopup,
LIcon,
LControlAttribution,
LControlZoom,
} = require("vue2-leaflet/dist/vue2-leaflet.min"));
({
Icon
} = require("leaflet"));
Vue2LeafletMarkerCluster = require('vue2-leaflet-markercluster')
}
import "leaflet/dist/leaflet.css";
export default {
components: {
"l-map": LMap,
"l-tile-layer": LTileLayer,
"l-marker": LMarker,
"l-popup": LPopup,
"l-icon": LIcon,
"l-control-attribution": LControlAttribution,
"l-control-zoom": LControlZoom,
"v-marker-cluster": Vue2LeafletMarkerCluster,
},
mounted() {
if (!process.server) //probably not needed but whatever
{
// This makes sure the common error that the images are not found is solved, and also adds the settings to it.
delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
// iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'), // if you want the defaults
// iconUrl: require('leaflet/dist/images/marker-icon.png'), if you want the defaults
// shadowUrl: require('leaflet/dist/images/marker-shadow.png') if you want the defaults
shadowUrl: "/icon_shadow_7.png",
iconUrl: "/housemarkerblue1.png",
shadowAnchor: [10, 45],
iconAnchor: [16, 37],
popupAnchor: [-5, -35],
iconSize: [23, 33],
// staticAnchor: [30,30],
});
}
},
And there's proof using nuxt build --modern=server --analyze
https://i.stack.imgur.com/kc6q4.png
I am replicating my answer here since this is the first post that gets reached searching for this kind of problem, and using the solutions above still caused nuxt to crash or error in my case.
You can import your plugin in your mounted hook, which should run in the client only. So:
async mounted() {
const MyPlugin = await import('some-vue-plugin');
Vue.use(MyPlugin);
}
I do not know about the specific plugin you are trying to use, but in my case I had to call Vue.use() on the default property of the plugin, resulting in Vue.use(MyPlugin.default).

How do I import Three.js into my Nuxt project

I want to import modules in examples folder in THREE.js such as OBJLoader into my Nuxt Project.
I can import main folder of THREE, but error occurs when trying to import modules in examples folder.
Tried these steps in official docs.
https://threejs.org/docs/index.html#manual/en/introduction/Import-via-modules
I'm getting error below
SyntaxError
Unexpected token {
<template>
</template>
<script>
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
export default{
}
</script>
here are my github repository
https://github.com/ksuhara/threejs-test
Finally I could find what was wrong.
Well, it has to do with nuxt building system. When using third parts libs, you should add them into nuxt.config.js bild->transpile array so it can be included as a dependency with Babel.
transpile: [
"three"
]
Ref: https://nuxtjs.org/api/configuration-build#transpile
Threejs must be run on the client side so enclosed the component with <client-only> tag and loaded it dynamically with const MyComponent = () => import('~/path/to/MyComponent.vue'); but now I am getting the error on server side.
Finally I managed to do it like this!
<template>
<div>
<client-only>
<threejs-component />
</client-only>
</div>
</template>
<script>
export default {
components: {
ThreejsComponent: process.browser ? () => import('~/path/to/ThreejsComponent.vue') : null
}
}
</script>
inside ThreejsComponent.vue are all the threejs imports

FontAwesome with Vuetify - How to include Font Awesome icons within the v-icon component

Hopefully someone will know where I have gone wrong here - I'm trying to implement the Font Awesome package with Vuetify. Font Awesome is all imported and ready to go (setup is indentical to projects which I have Font Awesome successfully integrated):
My bare basics main.js file:
import '#babel/polyfill'
import Vue from 'vue'
import './plugins/vuetify'
import App from './App.vue'
import store from './store'
import './registerServiceWorker'
import { library } from '#fortawesome/fontawesome-svg-core'
import { faCode } from '#fortawesome/pro-solid-svg-icons'
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
library.add(faCode)
Vue.component('font-awesome-icon', FontAwesomeIcon)
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app')
And within a component I am referencing an icon as follows:
My Component.vue:
<template>
...
<v-btn>
<v-icon>fas fa-code</v-icon>
</v-btn>
...
</template>
^ Where I have left out superfluous code*.
So, my question is - how do we integrate Font Awesome within Vuetify's v-icon component?
For reference, I’m using what is outlined here:
https://vuetifyjs.com/en/components/icons
Which is identical to what I have prescribed above, but sadly my icon does not display...
Update: I specifically want a solution which doesn't include adding the rather heavy Font Awesome all.css file (<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">) - instead importing on an icon by icon need. (the overall weight of the minified all.css file is 52kb in v.5.2.0.
You can use tree shaking.
Since you are looking for an option to avoid loading all icons into vue/vuetify, I suggest that you utilize the tree shaking method and add each icon you want to use, manually. This can be a bit tedious but adding in icons on demand will be beneficial in the long term - as webpack will just bundle up the ones you specify.
Please note:
In this tutorial, I assume that the reader has the Pro package. If you only want to use the free ones just remove anything resembling pro from the mix
Below you can see my preferred way of doing this with vuetify and using SVGs with v-icon and v-text/v-html:
First we have to install the icons:
(open up your terminal/command-prompt inside your project and install)
$ npm i --save #fortawesome/fontawesome-svg-core // this is the svg core, it is needed.
$ npm i --save #fortawesome/vue-fontawesome // Vue integration *
$ npm i --save #fortawesome/free-brands-svg-icons // Branding icons
$ npm i --save #fortawesome/free-regular-svg-icons // only for FA5 free **
$ npm i --save #fortawesome/free-solid-svg-icons // only for FA5 free **
$ npm i --save #fortawesome/pro-regular-svg-icons // Pro icons regular type
$ npm i --save #fortawesome/pro-light-svg-icons // Pro icons light type
$ npm i --save #fortawesome/pro-solid-svg-icons // Pro icons solid type
$ npm i --save #fortawesome/pro-duotone-svg-icons // Pro icons duotone type ***
( * ) The vue integration bundle more info
( ** ) Only needed for free icons, if you own Pro and followed the instructions here, they are are included in pro already.
( *** ) As of writing, the duotone icons are not completely integrated yet, beware of errors.
Then lets add this to our vuetify configuration:
I assume here that you use vuejs with javascript (not typescript) and that you've installed vuetify through vue add vuetify. The vuetify.js file should reside inside the plugins folder in your src folder. Your milage may vary.
// src/plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import { library } from '#fortawesome/fontawesome-svg-core' // Core SVG
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome' // Integration
// ... there should be more here, but see next part below ...
Vue.component('font-awesome-icon', FontAwesomeIcon) // add it to vue
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'faSvg', // The bees knees, what most people are looking for.
},
});
Ok, now that we've added the main components of FontAwesome 5, let's use treeshaking to instruct which icons we'd like to use for our project. I will only use two icons as examples: fa-plus and fa-user-circle, and I will add them for three of the Font Awesome Pro 5 packages we installed (Light, Regular and Duotone) and then I will add some others (bars and user) for the solid, to see how this can be done in both ways at the same time.
So back to our vuetify.js file, we replace
// ... there should be more here, but see next part below ...
with the following (note camelcase):
// src/plugins/vuetify.js
// ...
import {
faBars,
faUser
} from '#fortawesome/pro-solid-svg-icons'
import {
faPlus as farPlus,
faUserCircle as farUserCircle
} from '#fortawesome/pro-regular-svg-icons'
import {
faPlus as falPlus,
faUserCircle as falUserCircle
} from '#fortawesome/pro-light-svg-icons'
import {
faPlus as fadPlus,
faUserCircle as fadUserCircle
} from '#fortawesome/pro-duotone-svg-icons'
// ...
Quick note: If you still would like to add the entire library of these, you can do that by importing like so: import { far } from '#fortawesome/pro-regular-svg-icons' (for regular) and so on.
As you can see, we've now added fa-plus and fa-user-circle to our project. From here, we need to add them to the library we imported into the vuetify.js config. (don't sweat, the whole file can be seen below in the code snippet.):
// src/plugins/vuetify.js
// ...
Vue.component('font-awesome-icon', FontAwesomeIcon)
library.add(
faBars, faUser,
farPlus, falPlus, fadPlus,
farUserCircle, falUserCircle, fadUserCircle
)
/// ...
Now that we've added them to the library, we need to hand them over to vuetify. Vuetify has some special icons that they use for things like the <v-app-bar-nav-icon></v-app-bar-nav-icon> (hamburger menu). We can customize these, and add our own to the mix (if we'd like). I do this by defining a constant and add all the icons I need in there, like so:
const CUSTOM_ICONS = {
add: { // custom icon I want to use
component: FontAwesomeIcon,
props: {
icon: ['fad', 'plus']
}
},
menu: { // used for the nav-icon by vuetify
component: FontAwesomeIcon,
props: {
icon: ['fas', 'user']
}
}
}
and then we add this constant to the config like so:
export default new Vuetify({
icons: {
iconfont: 'faSvg',
values: CUSTOM_ICONS,
},
});
You could also add them directly into the values variable, but I find it more readable to do it through a constant.
Now we can use these in templates, appends or prepends:
<template>
<v-app>
<!-- reference the whole path -->
<v-icon>$vuetify.icons.add</v-icon>
<!-- but this is easier -->
<v-icon>$add</v-icon>
<v-select
:items="direction"
label="Select direction"
menu-props="auto"
prepend-icon="$unfold" <!-- short version -->
append-icon="$vuetify.icon.unfold" <!-- long version -->
>
</v-select>
</v-app>
</template>
Finally, here is the complete example:
// src/plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import { library } from '#fortawesome/fontawesome-svg-core' // Core SVG
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome' // Integration
import {
faBars,
faUser
} from '#fortawesome/pro-solid-svg-icons'
import {
faPlus as farPlus,
faUserCircle as farUserCircle
} from '#fortawesome/pro-regular-svg-icons'
import {
faPlus as falPlus,
faUserCircle as falUserCircle
} from '#fortawesome/pro-light-svg-icons'
import {
faPlus as fadPlus,
faUserCircle as fadUserCircle
} from '#fortawesome/pro-duotone-svg-icons'
Vue.component('font-awesome-icon', FontAwesomeIcon)
library.add(
faBars, faUser,
farPlus, falPlus, fadPlus,
farUserCircle, falUserCircle, fadUserCircle
)
const CUSTOM_ICONS = {
add: { // custom icon I want to use
component: FontAwesomeIcon,
props: {
icon: ['fad', 'plus']
}
},
menu: { // used for the nav-icon by vuetify
component: FontAwesomeIcon,
props: {
icon: ['fas', 'user']
}
}
}
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'faSvg',
values: CUSTOM_ICONS,
},
});
<template>
<v-app>
<!-- reference the whole path -->
<v-icon>$vuetify.icons.add</v-icon>
<!-- but this is easier -->
<v-icon>$add</v-icon>
<v-select
:items="direction"
label="Select direction"
menu-props="auto"
prepend-icon="$unfold" <!-- short version -->
append-icon="$vuetify.icon.unfold" <!-- long version -->
>
</v-select>
</v-app>
</template>
Suggestion separate files for better reading
We can separate the fontAwesome logic to another file:
So we have 2 files:
the fontAwesome.js where you do all the logic belonging to fontAwesome
the vuetify.js you will import the Icons from fontAwesome.js
// src/plugins/fontAwesome.js
import { library } from '#fortawesome/fontawesome-svg-core' // Core SVG
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome' // Integration
import {
faBars,
faUser
} from '#fortawesome/pro-solid-svg-icons'
import {
faPlus as farPlus,
faUserCircle as farUserCircle
} from '#fortawesome/pro-regular-svg-icons'
import {
faPlus as falPlus,
faUserCircle as falUserCircle
} from '#fortawesome/pro-light-svg-icons'
import {
faPlus as fadPlus,
faUserCircle as fadUserCircle
} from '#fortawesome/pro-duotone-svg-icons'
library.add(
faBars, faUser,
farPlus, falPlus, fadPlus,
farUserCircle, falUserCircle, fadUserCircle
)
const CUSTOM_ICONS = {
add: { // custom icon I want to use
component: FontAwesomeIcon,
props: {
icon: ['fad', 'plus']
}
},
menu: { // used for the nav-icon by vuetify
component: FontAwesomeIcon,
props: {
icon: ['fas', 'user']
}
}
}
export { CUSTOM_ICONS }
// src/plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import { CUSTOM_ICONS } from "./fontAwesome"
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'faSvg',
values: CUSTOM_ICONS
},
});
<template>
<v-app>
<!-- reference the whole path -->
<v-icon>$vuetify.icons.add</v-icon>
<!-- but this is easier -->
<v-icon>$add</v-icon>
<v-select
:items="direction"
label="Select direction"
menu-props="auto"
prepend-icon="$unfold" <!-- short version -->
append-icon="$vuetify.icon.unfold" <!-- long version -->
>
</v-select>
</v-app>
</template>
Further reading:
Why use Font Awesome with library as a concept?
Vuetify: how to install Font Awesome 5
Using Font Awesome with VueJS
For a Nuxt/Vuetify Project:
Complementing the above answer, you can also set it up in the Vuetify configuration file, that is created during the project installation ( "plugins/vuetify.js" ), adding the "iconfont" prop:
import '#fortawesome/fontawesome-free/css/all.css' // Ensure you are using css-loader
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify, {
iconfont: 'fa'
})
Now, use with the icon component like this:
<v-icon>fab fa-vuejs</v-icon>
A simple solution is posted under framework options in Vuetify: https://vuetifyjs.com/en/framework/icons
Install icons library using NPM or yarn:
npm install #fortawesome/fontawesome-free -D
Config - For a simple vue project
Add this to your main.js
import '#fortawesome/fontawesome-free/css/all.css'
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify, {
iconfont: 'fa'
})
Config - For a nuxt + vuetify project
Create a js file(eg icons.js) under plugins
import '#fortawesome/fontawesome-free/css/all.css'
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify, {
iconfont: 'fa'
})
Add this to your plugins in nuxt.config.js
{ src: '~/plugins/icons.js', ssr:false }
Usage
Now you can access font awesome icons using v-icon or append/prepend in component like:
<v-slider
v-model="energy"
color="red"
label="Energy"
min="1"
max="100"
thumb-label="always"
prepend-icon="fa-burn"
></v-slider>
Ok, so using the above commenter's suggestion, I have managed to get it working by using the standard vue-font-awesome method of including font awesome icon components, swopping <v-icon> out for such that what I used in my question:
<v-btn>
<v-icon>fas fa-code</v-icon>
</v-btn>
...becomes:
<v-btn fab dark small color="black" v-on:click="addCodeBlock">
<font-awesome-icon :icon="['fas', 'code']"/>
</v-btn>
import font-awesome in src/main.js:
import Vue from 'vue'
import './plugins/vuetify'
import App from './App.vue'
import router from './router'
import 'font-awesome/css/font-awesome.css'
new Vue({
router,
render: h => h(App),
}).$mount('#app')
then define iconfont in src/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import 'vuetify/src/stylus/app.styl'
Vue.use(Vuetify, {
iconfont: 'fa4' // 'md' || 'mdi' || 'fa' || 'fa4'
})