Open14

[Astro] アイコンを表示する

平田直毅平田直毅

AstroはSSRでしか使用しないので、SSRを前提とする。
設定はこんな感じ。

astro.config.mjs
export default defineConfig({
  // SSR type configuration
  output: 'server',
  adapter: node({
    mode: 'standalone'
  }),
  server: { port: 3000, host: true },
  ...
});
平田直毅平田直毅

astro-iconパッケージを追加すると

astro.config.mjs
import icon from "astro-icon";
export default defineConfig({
  ...
  integrations: [icon()],
});
index.astro
import { Icon } from 'astro-icon/components';
---
<Icon name="mdi:account" />

でアイコンが表示できるらしい。でない。

平田直毅平田直毅

アイコンリソースが必要のようだ。
@iconify-json/mdiパッケージを追加する。⇒ アイコン出た。

平田直毅平田直毅

必要なアイコンのリソースだけを読み込むように制限を加える。

astro.config.mjs
export default defineConfig({
  ...
  integrations: [
    //  icon(),  // [A]
    //  icon({  // [B]
    //    include: {
    //      mdi: ["*"],
    //    },
    //  },
    icon({  // [C]
      include: {
        mdi: ["account"]
      },
    }),
  ],
});

Aパターン、Bパターンはファイルサイズは同じ。
Cパターンでは大幅にサイズが小さくなる。(2863KB → 5KB)
しかし使用するアイコンをすべて列挙するのは現実的ではない。

平田直毅平田直毅

自動的に.astro/icon.d.tsにアイコンの型定義ファイルが追加された。

平田直毅平田直毅

VueやReactコンポーネントでアイコンを表示するには、@iconify/vue@iconify/reactパッケージを使用する。

Vue、Reactとも以下の書式で表示するがアイコンの表示が遅延する。

import { Icon } from '@iconify/vue'
あるいは
import { Icon } from '@iconify/react'
<Icon icon="mdi:home" />
平田直毅平田直毅

unplugin-iconsパッケージでViteに処理を加える。
https://github.com/unplugin/unplugin-icons

astro.config.mjs
import react from '@astrojs/react'
import vue from "@astrojs/vue"
import Icons from 'unplugin-icons/vite'

export default defineConfig({
  ...
  integrations: [react(), vue()],
  vite: {
    plugins: [Icons()]
  }
})

アイコンの取得方法は1つずつ取得する方法に変わる。Vueでは遅延が止まった。

import CheckFill from "~icons/ph/check-fill"
<CheckFill color="red" width="500" height="500" />
平田直毅平田直毅

Reactでは

Cannot read properties of null (reading 'useCallback')

のエラーが出る。

平田直毅平田直毅

あるアイコンセットを使用するには、アイコンリソースを読み込む必要がある。
astro-iconunplugin-iconsパッケージを使用して以下のように設定する。

アイコンセットは指定する必要がある。
@iconify-json/xxx形式のパッケージのアイコンリソースを読み込んでおき、includeセクションに記述する。

astro.config.mjs
import icon from 'astro-icon'
import Icons from 'unplugin-icons/vite'

export default defineConfig({
  ...
  integrations: [
    ...
    icon({
      include: {
        mdi: ['*']
      }
    })
  ],
  vite: {
    plugins: [Icons()]
  }
})

これでAstroファイルでもVue、Reactコンポーネントでも表示可能になる。

平田直毅平田直毅

アイコンの表示が遅れるのは、クライアント側の処理でアイコンが追加されているから。