Nuxt-fontawesomeでUnknown custom element:というエラーとFacebookなど一部のiconが表示されない問題の解決法



[nuxt-fontawesome公式のページ](https://www.npmjs.com/package/nuxt-fontawesome)にあるようにやっても、
 >[Vue warn]: Unknown custom element: <fa> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

というエラーが出てできなかったので同じようにエラーが出て悩んでいる人の役に立てばと思います。


#Unknown custom element:~ エラーの解決法
vue-fontawesomeを使う。
[実はvue-fontawesomeの公式のページ](https://github.com/FortAwesome/vue-fontawesome#nuxtjs)にもNuxtでの使い方の説明がそのままあるのですが、Nuxtを使うなら普通nuxt-fontawesomeを使うことを考えるでしょうし、冒頭のエラーメッセージでググってもvue-fontawesomeのページはヒットしないので、エラーが出てググった時にこの記事にたどり着いて解決できるようにと思って書きました。


##手順

```javascript
import Vue from 'vue'
import { library, config } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { fab } from '@fortawesome/free-brands-svg-icons'

// This is important, we are going to let Nuxt.js worry about the CSS
config.autoAddCss = false

// You can add your icons directly in this plugin. See other examples for how you
// can add other styles or just individual icons.
library.add(fas)

// Register the component globally
Vue.component('font-awesome-icon', FontAwesomeIcon)
```

```nuxt.config.js
plugins: [
  '~/plugins/fontawesome.js'
]
```
```index.vue
    <font-awesome-icon icon="laptop" size="4x" />
    <font-awesome-icon icon='facebook' style="color: #4267B2; font-size: 72px;"/>
```
##結果
これで以下のように表示されるかと思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116252/d479ac1b-8ca1-4341-adf4-ee07513521ba.png)


#Facebookなど一部のiconが表示されない問題の解決法
しかしこれではfacebookのアイコンが表示されていません。コンソールを見てみると、
>Could not find one or more icon(s) 
{prefix: "fas", iconName: "facebook"}
iconName: "facebook"
prefix: "fas"

と出ているかと思います。
##原因

悩んだのですが、色々と調べた結果

```Javascript
function normalizeIconArgs (icon) {
  if (icon === null) {
    return null
  }

  if (typeof icon === 'object' && icon.prefix && icon.iconName) {
    return icon
  }

  if (Array.isArray(icon) && icon.length === 2) {
    return { prefix: icon[0], iconName: icon[1] }
  }

  if (typeof icon === 'string') {
    return { prefix: 'fas', iconName: icon }
  }
}
```

どうやらvue-fontawesomeのソースコード上では上のような処理になっていて、Stringを渡すとprefixがfasだと解釈されてしまうようです。しかし、以下のようにFacebookのアイコンはprefixがfabなので、上記のエラーが出てしまっていました。ここでは、prefixとiconNameをkeyに持つobjectをvue-fontawesomeに渡す必要があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116252/f27a418c-9851-d9d9-9609-2926210de3fc.png)
https://fontawesome.com/icons/facebook?style=brands

##手順

よって、まず以下をfontawesome.jsに追加。

```Javascript
import { fab } from '@fortawesome/free-brands-svg-icons'
library.add(fab)
```

vueファイルでは次のように変えましょう。

```index.vue
<font-awesome-icon v-bind:icon="{ prefix: 'fab', iconName: 'facebook' }" style="color: #4267B2; font-size: 72px;"/>
```
:iconは
v-bind:iconの省略記法です。このようにしてobjectを渡し、勝手にfasがprefixであると解釈されないようにします。

##結果
これでこのように表示されているのではないでしょうか？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/116252/292dc99d-1f7f-28d4-7129-8d03d8b6c55d.png)


#おまけ　fontawesomeのベストプラクティスとして

GitHubとここで挙げた例では

```Javascript
library.add(fas)
library.add(fab)
```

のようにしていましたが、これだとプロジェクトのサイズが不必要に膨れ上がってしまうので、

```javascript
import { faFacebook } from "@fortawesome/free-brands-svg-icons";
import { faGithub } from "@fortawesome/free-brands-svg-icons";


library.add(faFacebook);
library.add(faGithub);
```

このように必要なものだけをimportするようにしましょう！



以上です。





参考：
https://github.com/FortAwesome/vue-fontawesome#nuxtjs
https://www.endpoint.com/blog/2018/07/12/vue-fontawesome-facebook-twitter