🐙

【React】font-awesomeのインストールと使い方(Next.js, TypeScript)

2023/05/02に公開

Reactでfont-awesomeを使いたいと思い、公式ドキュメントをさらったので、
意訳しつつ簡単にまとめました。

Reactだけでなく、Next.jsとTypeScriptでの使い方も書いてます。

公式ドキュメントはこちら

インストール

各種パッケージをインストールします。

1. SVGコアパッケージのインストール

最初にコアパッケージをインストールします。

npm

npm i --save @fortawesome/fontawesome-svg-core

yarn

yarn add @fortawesome/fontawesome-svg-core

2. アイコンパッケージのインストール

次にアイコンをインストールします。

無料のアイコンには2つの種類があります。

どちらもインストールしてもいいし、好きな方だけインストールしても良いです。

npm

npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons

yarn

yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/free-regular-svg-icons

3. react-fontawesomeパッケージのインストール

最後に、Font Awesome React componentのパッケージをインストールします。

npm

npm i --save @fortawesome/react-fontawesome@latest

yarn

yarn add @fortawesome/react-fontawesome@latest

公式ドキュメント該当ページ

使い方

使い方は主に3種類あります。

  • Dynamic Icon Importing
  • Add Individual Icons Explicitly
  • Add Icons Globally

Dynamic Icon Importing

動的にアイコンをインポートできます。
iconプロパティにアイコンの情報を渡します。

例えば、こんな感じです。

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { icon } from '@fortawesome/fontawesome-svg-core/import.macro'

export const Hoge: React.FC = () => {
  return <FontAwesomeIcon icon={icon({name: 'coffee', family: 'sharp', style: 'solid'})} />;
}

nameは、アイコン名で、familyは全体のスタイル、styleは個別のスタイル?という感じみたいです。

Add Individual Icons Explicitly

個々にアイコンをインポートできます。
iconプロパティに固定のアイコンを指定します。

例えば、こんな感じです。

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faEnvelope } from '@fortawesome/free-solid-svg-icons'

export const Hoge: React.FC = () => {
  return <FontAwesomeIcon icon={faEnvelope} />;
}

Add Icons Globally

グローバルにアイコンをインポートできます。
iconプロパティにアイコンを指定するキーワードを渡します。(クラスっぽい)

上の方法を使えない場合は、このやり方でもインポートできるけど、
ファイルによっては使っていないアイコンまで含んでしまい、必要以上に大きいバンドルサイズになってしまうので、あまり推奨してないらしいです。

例えば、こんな感じです。

App.js

import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { faTwitter, faFontAwesome } from '@fortawesome/free-brands-svg-icons'
import { faHatCowboy } from '@fortawesome/pro-thin-svg-icons'
import { faHatChef } from '@fortawesome/sharp-solid-svg-icons'
import { faPlateUtensils } from '@fortawesome/sharp-regular-svg-icons'

library.add(fas, faTwitter, faFontAwesome, faHatCowboy, faHatChef, faPlateUtensils)

App.jsにて、library.add()で読み込んでおきます。

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'

export const Mailroom: React.FC = () => {
  return <FontAwesomeIcon icon="fa-solid fa-check-square" />
}

呼び出し先では、こんな感じで呼びます。

詳細はこちら

公式ドキュメント該当ページ

アイコンのスタイリング

reactでのアイコンのスタイリングは、通常のやり方と異なります。
HTMLではクラスで指定しますが、reactではプロパティで渡します。

Size(サイズの指定)

サイズ指定には2種類あってTシャツサイズ指定通常サイズ指定の2種類があります。

Tシャツサイズ

smとかlgなど、Tシャツサイズで指定ができます。
指定なし含めて2xsから2xlまでの7段階あります。

<FontAwesomeIcon icon="fa-solid fa-coffee" size="2xs" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="xs" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="sm" />
<FontAwesomeIcon icon="fa-solid fa-coffee" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="lg" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="xl" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="2xl" />

通常サイズ指定

x5など、x + 数字で指定できます。
x1からx10までの10段階あります。

<FontAwesomeIcon icon="fa-solid fa-coffee" size="1x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="2x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="3x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="4x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="5x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="6x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="7x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="8x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="9x" />
<FontAwesomeIcon icon="fa-solid fa-coffee" size="10x" />

※HTMLで指定されていたクラスでいうと、fa-2xsとかfa-4xに該当します。

公式ドキュメント該当箇所
公式ドキュメントスタイル概要

Fixed-width(アイコン幅の固定)

アイコンの幅を固定してくれます。
異なるアイコンサイズのものを縦に並べるときとかに役立つとのことです。なるほど〜

<FontAwesomeIcon icon="fa-solid fa-coffee" fixedWidth />

※HTMLで指定されていたクラスでいうと、fa-fwに該当します。

公式ドキュメント該当箇所
公式ドキュメントスタイル概要

Icons in a List(箇条書きリストのアイコン)

アイコンを使ったリスト(箇条書きリスト)に対して、
Fixed-widthと同じ効果を使って整列してくれます。

<FontAwesomeIcon icon="fa-solid fa-coffee" listItem />

※HTMLで指定されていたクラスでいうと、fa-ulfa-liに該当します。

公式ドキュメント該当箇所
公式ドキュメントスタイル概要

Rotate and Flip Icons(回転と反転)

回転させたり、反転させたりできます。

rotation(回転)

指定した角度ぶん、右に回転してくれます。

<FontAwesomeIcon icon="fa-solid fa-coffee" rotation={90} />
<FontAwesomeIcon icon="fa-solid fa-coffee" rotation={180} />
<FontAwesomeIcon icon="fa-solid fa-coffee" rotation={270} />

※HTMLで指定されていたクラスで言うと、fa-rotate-90にあたります。

flip(反転)

  • horizontal - 水平に反転(左右反転)
  • vertical - 垂直に反転(上下反転)
  • both - 上記どちらも(上下左右反転)
<FontAwesomeIcon icon="fa-solid fa-coffee" flip="horizontal" />
<FontAwesomeIcon icon="fa-solid fa-coffee" flip="vertical" />
<FontAwesomeIcon icon="fa-solid fa-coffee" flip="both" />

※HTMLで指定されていたクラスで言うと、fa-flip-horizontalfa-flip-bothにあたります。

公式ドキュメント該当箇所
公式ドキュメントスタイル概要

Animate Icons(アニメーション)

アニメーションを付与できます。
特に、ローディング中や進行中などを表現するために使われたりします。

アニメーションを見たほうが早いと思うので、使い方とアニメーションのリンクを貼ります。
アニメーション一覧はこちら

beat

<FontAwesomeIcon icon="fa-solid fa-heart" beat />

アニメーション

beatFade

<FontAwesomeIcon icon="fa-solid fa-circle-info" beatFade />

アニメーション

bouce

<FontAwesomeIcon icon="fa-solid fa-basketball" bounce />

アニメーション

fade

<FontAwesomeIcon icon="fa-solid fa-triangle-exclamation" fade />

アニメーション

flip

<FontAwesomeIcon icon="fa-solid fa-compact-disc" flip />

アニメーション

shake

<FontAwesomeIcon icon="fa-solid fa-bell" shake />

アニメーション

spin (spinReverse)

<FontAwesomeIcon icon="fa-solid fa-bell" spin />
<FontAwesomeIcon icon="fa-solid fa-compass" spin spinReverse />

アニメーション

spinPulse

<FontAwesomeIcon icon="fa-solid fa-spinner" spinPulse />

アニメーション

公式ドキュメント該当箇所
公式ドキュメントスタイル概要

Next.jsと使う

react-fontawesomeコンポーネントはNext.jsと相性が良いですが、正しく動作させるのに必要な設定があります。
(Next.jsは、CSSをその他多くのプロジェクトとは異なる方法で管理しているため、アイコンを正しく動作させるCSSが一部不足しており、巨大なアイコンが表示されてしまうと思います。)

初期設定

CSSを正しく動作させるために、以下をpages/_app.jsに追加してください。

pages/_app.js

↓↓↓ ここから ↓↓↓
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false
↑↑↑ ここまで ↑↑↑

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

※最新のpages/_app.jsの実装についてはこちらを参考にしてください。

import '@fortawesome/fontawesome-svg-core/styles.css'

この処理を行うことで、Next.jsプロジェクト内の.jsファイルで、直接CSSをインポートすることが可能になります。これを追加すると必要なWebpackの設定が完了します。

config.autoAddCss = false

autoAddCssをfalseにすることで、Font Awesomeのコアライブラリが<style>要素をページのheadタグ内に挿入することを防いでいます。

使い方

初期設定が済んだら、以下のようにアイコンを使うことができるようになります。

import Head from 'next/head'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faFaceRelieved } from '@fortawesome/pro-solid-svg-icons'

export default function Home() {
  return (
    <div className="container">
      <main>
        <h1 className="title">
          <FontAwesomeIcon icon={faFaceRelieved} />
          Welcome to <a href="https://nextjs.org">Next.js!</a>
        </h1>
      </main>
    </div>
  )
}

トラブルシュート

./styles.cssのインポートに失敗する

Module not found: Package path ./styles.css is not exported from package`

新しいバージョンのNext.jsを使っていると、このエラーが起きる可能性があるらしいです。
解決するには、_app.jsのスタイルのインポート方法を以下に変更してください。

- import '@fortawesome/fontawesome-svg-core/styles.css'
+ import '../node_modules/@fortawesome/fontawesome-svg-core/styles.css'

※上記については一時的な解決策であり、font-awesomeのバージョン6以降で対応を入れるかもしれないらしいです。

Duotoneアイコンが表示されない

duotoneアイコンを使おうとしているのにsolidアイコンが表示されてしまう場合は、CSSがインストールされていない可能性があります。
(duotoneを再現するために、font-awesomeはCSSでopacityやセカンダリレイヤを設定しています。)

公式ドキュメント該当箇所

TypeScriptと使う

型付けはパッケージに含まれていますが、ほとんどの型は基底のAPIライブラリ(@fortawesome/fontawesome-svg-core)で定義されているので、ライブラリをインポートする(グローバルインポートする)必要があるみたい?です。

初期設定

ライブラリに使うアイコンを登録します。
(以下の例では全てのアイコンを登録してます)

import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'

library.add(fas)

// ...

使い方

型情報と共にアイコンを定義します。

以下の例では、IconLookup型とIconDefinition型、findIconDefinition関数をインポートしています。
IconLookup型の検索値を定義し、findIconDefinition関数に渡して検索した結果をIconDefinition型の結果に格納しています。

これをFontAwesomeIconコンポーネントのiconプロパティに渡してあげると動作するみたいです。

import {
  IconLookup,
  IconDefinition,
  findIconDefinition
} from '@fortawesome/fontawesome-svg-core'

const coffeeLookup: IconLookup = { prefix: 'fa-solid', iconName: 'fa-coffee' }
const coffeeIconDefinition: IconDefinition = findIconDefinition(coffeeLookup)

// ...

export class App extends React.Component {
  render() {
    return (
      <div className="App">
        <h1>
          <FontAwesomeIcon icon={coffeeIconDefinition} />
        </h1>
      </div>
    )
  }
}

※型情報を使いたい人向けに、あえて上記のような面倒な例を掲載しましたが、あくまでこのように型を使えるという例であり、通常はこのように使う必要はないと思う、と書いてありました。

※上の例に出てきたIconLookupIconDefinitionといった型は、実際には@fortawesome/fontawesome-common-typesで定義されていますが、利便性のため@fortawesome/fontawesome-svg-core@fortawesome/free-solid-svg-iconsその他アイコンパッケージから再エクスポートされているらしいです。そのほかにどんな型がエクスポートされているかを確認したい場合は、index.d.tsを見てねとのことです。

公式ドキュメント該当箇所

トラブルシュート

バージョン4からのアップデート

大きな変更が入っているため、変更箇所が発生する可能性があります。バージョンアップする際は、正しく動作しているかの確認をしてください。

React Nativeで使いたい

react-fontawesomeは、React専用です。React Nativeで使いたい場合は、こちらを参考にしてください。

tree-shakingが動かない...

tree-shakingについての詳細なドキュメントを用意しているので読んでみてください。

react-fontawesomeを使おうとするとBabel/Babel-loaderのエラーが出ます

MacかLinuxを使っている場合は、brew updatebrew upgradeを実行し最新のバージョンを使っていることを確認してください。
または、package.json.lockNode_Modulesフォルダを削除してnpm installまたはyarn installを実行して再インストールしてください。

公式ドキュメント該当ページ

その他

ユニットテスト

アイコンを含むコンポーネントをテストしたいとき...

インポートの方法にグローバルインポート以外を採用している場合

その場でアイコンをインポートしてテストに使ってください。

インポートの方法にグローバルインポートを採用していて、かつテスト対象にrootコンポーネントが含まれていない場合

以下のエラーが出ると思います。

Could not find icon { prefix: 'fas', iconName: 'chevron-right' }

もしこのエラーが発生し、またアイコン自体がそこまでテストにとって重要でない場合は、以下のようにアイコンのモックを作成して使うことができます。

export function FontAwesomeIcon(props) {
  return <i classname="fa"></i>
}

Discussion