6

I'm facing an error with Nuxtjs when I try to use the vue-fontawesome framework and also the @nuxtjs/fontawesome framework, this is the error:

[nuxt] [request error] Cannot read properties of undefined (reading 'component')
    at $id_c50a96b3 (./.nuxt/dist/server/server.mjs:3239:31)
    at async __instantiateModule__ (./.nuxt/dist/server/server.mjs:19193:3)

this is my code in nuxt.config.ts:

import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
  modules: [
    '@nuxtjs/fontawesome'
  ],

  fontawesome: {
    icons: {
      solid: ['faXmark']
    }
  }
})

And this is the component where I want to use the icon:

<template>
  <div :class="props.className">
    <font-awesome-icon icon="xmark" />
    <slot />
  </div>
</template>

By the way, the error just appear when I try to load the page, not when I run it.

kissu
  • 40,416
  • 14
  • 65
  • 133
FRostri
  • 357
  • 1
  • 5
  • 11
  • It looks like the error is not coming from what you've shared. Isn't there a `.component` somewhere in your code? The left part looks to be undefined sometimes. – kissu Apr 29 '22 at 05:00
  • No, theres no other file that I created that have some line with that, but actually the rest of the error show this: `at $id_c50a96b3 (./.nuxt/dist/server/server.mjs:3239:31) at async __instantiateModule__ (./.nuxt/dist/server/server.mjs:19193:3)` – FRostri Apr 29 '22 at 05:13
  • Oh, so you're using Nuxt3. Not sure if this module is compatible with it. – kissu Apr 29 '22 at 05:59
  • Since last commit was 15months ago, we can be sadly confident it's not compatible with Nuxt 3. You'll have to find another way to install your fontawesome library with a plugin / module of your own! – Kapcash Apr 29 '22 at 07:02

3 Answers3

10

I recommend this solution by antfu, which is IMO by far the best approach to work with any kind of icons: https://github.com/antfu/unplugin-icons
Check the more in-depth article explaining why and how the whole thing works.


Here's a quick way on how to use it with Nuxt3, first off the requirements:

  • be sure to use Node v16 or later
  • start a new Nuxt3 project: pnpm dlx nuxi init nuxt3-unplugin-icons
  • I'm using PNPM, so pnpm i --shamefully-hoist
  • add the aforementioned package with pnpm add -D unplugin-icons

Get this in your nuxt.config.ts file

// @ts-nocheck
import { defineNuxtConfig } from 'nuxt'
import Icons from 'unplugin-icons/vite'

export default defineNuxtConfig({
  vite: {
    plugins: [
      Icons({
        // the feature below is experimental ⬇️
        autoInstall: true
      })
    ]
  }
})

I don't know how to fix the types, so I just ignored the check here.


Once done, you can go to icones.js and look for your specific icon, click on it and you'll see this

enter image description here

Pay attention to the format being [collection-id]:[name], so in your case it's fa6-solid:xmark.

Now you can go to any .vue file and to convert your fa6-solid:xmark format into ~icons/fa6-solid/xmark while importing it.

<script setup>
import IconXmark from `~icons/fa6-solid/xmark`
</script>

<template>
  <icon-xmark style="font-size: 2em; color: blue" />
</template>

Your Nuxt3 project will now be able to auto-install the related package for you.

enter image description here

And that's all!


This autoInstall feature works most of the time but is not 100% battle-tested.
I've noticed that it is only able to install 2 icon packs at the same time (a simple restart of the server fixed the issue tho).

If the auto install feature failed, you can always go to npm and look for @iconify-json/[your collection id] aka @iconify-json/fa6-solid in your case.
NPM is quite good at suggestion the good one from what I've seen.

enter image description here


Here's an example on how to use some other icons

<script setup>
import IconXmark from '~icons/fa6-solid/xmark'
import IconAccountBox from '~icons/mdi/account-box'
import TastyPizza from '~icons/noto-v1/pizza'
import IconPs from '~icons/ri/playstation-line'
</script>

<template>
  <icon-xmark style="font-size: 2em; color: blue" />
  <icon-account-box style="font-size: 2em; color: red" />
  <tasty-pizza style="font-size: 2em" />
  <icon-ps style="font-size: 2em" />
</template>

And the actual result, totally customizable with CSS as you can see

enter image description here

You can check my github repo for a fully working example in case it's needed.

PS: an auto-import feature is in the works. Feel free to subscribe to the Github PR for more updates.

PS2: that one could even be used with dynamic components if you have a pre-defined array of possible icons so that the bundler can know them in advance thanks to an analytical read.

kissu
  • 40,416
  • 14
  • 65
  • 133
5

You can also use the rather new package nuxt-icon which is made by the CEO of NuxtLabs and used in the nuxt3/content2 starter template content-wind.

Instalation

npm install --save-dev nuxt-icon

yarn add --dev nuxt-icon

Setting up Nuxt 3

nuxt.config.ts

export default defineNuxtConfig({
   modules: ['nuxt-icon']
})

Usage

Just copy and paste name of icon you want from icones.js.org. Package will fetch icon and paste to your code. You have 100k+ icons to pick.

<Icon name="logos:google-icon"></Icon>
<Icon name="logos:facebook"></Icon>
<Icon name="logos:apple" fill="#97a3b6"></Icon>
Mises
  • 4,251
  • 2
  • 19
  • 32
patbird
  • 51
  • 1
  • 3
  • Could you edit your answer with some instructions on how does it work exactly? Usually, a few hyperlinks are not enough for an answer. – kissu Sep 22 '22 at 07:30
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/32777019) – user16217248 Sep 27 '22 at 23:21
  • 1
    This is how you should write an answer. I edited the answer because it is the best library for icons right now. – Mises Oct 25 '22 at 22:59
  • @Mises haha, you could have posted your own answer at this point. – kissu Oct 26 '22 at 00:18
  • 1
    @kissu No make sense repeating answer. XD I'm not greedy like you. XD – Mises Oct 26 '22 at 00:46
  • @Mises if you're adding a substantial amount of explanation that could be deserving it's own answer, I don't feel like it's being greedy. But you do as you'd like for sure. – kissu Oct 26 '22 at 10:12
  • @kissu I'm just messing with you – Mises Oct 26 '22 at 12:21
1

Only applies when working with custom svg icons

I usually use vite-svg-loader when I'm working with custom svg icons (no icon framework). This also works with Nuxt 3.

yarn add vite-svg-loader --dev

nuxt.config.ts

import svgLoader from 'vite-svg-loader'

export default defineNuxtConfig({
  vite: {
    plugins: [
      svgLoader({})
    ]
  }
})

When the setup is done, I create a new component that I can use later in other components (components/IconLoader.vue):

<template>
  <component :is="icon" />
</template>

<script>
  const props = defineProps<{ name: string }>()
  const icon = computed(() => 
    defineAsyncComponent(() => import(`../assets/icons/${props.name}.svg`))
  )
</script>

Now I can easily show icons with our new custom icon loader component (e.g. App.vue) :

<template>
  <icon-loader name="calendar" /> // assuming there is a calendar.svg file in your assets folder.
</template>

I usually get my icons from https://heroicons.dev, they work great with Tailwind.

PeeJee
  • 536
  • 6
  • 22