icon
@nuxt/icon

Iconifyの20万以上のすぐに使えるアイコンを備えたNuxt用アイコンモジュール。

nuxt-icon

Nuxt Icon

npm versionnpm downloadsLicenseNuxtVolta board

200,000以上のすぐに使えるアイコンを、IconifyをベースにNuxtアプリケーションに追加します。

機能 ✨

  • Nuxt 3 対応
  • SSR対応
  • Iconify経由で200,000のオープンソースベクターアイコンをサポート
  • CSSモード / SVGモードの両方をサポート
  • カスタムSVGのサポート(Vueコンポーネント経由、またはローカルSVGファイル経由)

!NOTE このモジュールは、より良い開発者エクスペリエンスとパフォーマンスのために完全に書き直されたv1.0バージョンをご覧いただいています。v0.6から移行する場合は、変更点の全リストについてこちらのPRをご確認ください。

セットアップ ⛓️

以下のコマンドを実行して、モジュールをプロジェクトに追加します

npx nuxi module add icon

これで、コンポーネントで<Icon />を使用できるようになります!

✨ VS Codeを使用している場合は、@antfuによるIconify IntelliSense拡張機能を使用できます。

手動セットアップ

モジュールは手動でインストールできます

npm i -D @nuxt/icon

nuxt.config.tsを更新します

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

レガシーモジュールnuxt-iconがインストールされている場合は、modulesリストから削除することをお勧めします。

使用方法 👌

プロップス

  • name (必須): アイコン名またはグローバルコンポーネント名
  • size: アイコンサイズ (デフォルト: 1em)
  • mode: アイコンのレンダリングモード (svg または css、デフォルト: css)

属性:

Iconifyのアイコンを使用する場合、レンダリングモードに基づいて<span>または<svg>が作成されます。ネイティブ要素のすべての属性を指定できます。

<Icon name="uil:github" style="color: black" />

TailwindCSS v4:

TailwindCSS v4とcssモードを使用する場合、Nuxtのアプリ設定でcssLayerを設定する必要があります。

// ~/app.config.ts
export default defineAppConfig({
  icon: {
    mode: 'css',
    cssLayer: 'base'
  }
})

Iconifyデータセット

https://icones.js.orgコレクションから任意の名前を使用できます。

<Icon name="uil:github" />

i-プレフィックス (例: i-uil-github) をサポートしています。

アイコンデータをローカルにインストールすることを強くお勧めします。

npm i -D @iconify-json/collection-name

例えば、uil:githubアイコンを使用するには、@iconify-json/uilでコレクションをインストールします。これにより、アイコンはローカルまたはサーバーレス関数から提供され、SSRとクライアント側の両方でより高速で信頼性が高くなります。

!NOTE すべてのIconifyアイコンを含めるために@iconify/jsonパッケージをインストールできることをご存じかもしれません。これはサーバーバンドルサイズとビルドパフォーマンスを増加させるため、お勧めしません。もしそうすることを選択する場合は、必要なコレクション名を明示的に指定することをお勧めします。

export default defineNuxtConfig({
  modules: ['@nuxt/icon'],
  icon: {
    serverBundle: {
      collections: ['uil', 'mdi'] // <!--- this
    }
  }
})

Vueコンポーネント

nameがグローバルに登録されたコンポーネントと一致する場合、そのコンポーネントとしてレンダリングされます(この場合、modeは無視されます)。

<Icon name="MyComponent" />

MyComponentcomponents/global/フォルダ内にある必要があります(を参照)。

!TIP コンポーネント名を変更することもできます。

export default defineNuxtConfig({
  icon: {
    componentName: 'NuxtIcon'
  }
})

カスタムローカルコレクション

ローカルSVGファイルを使用して、カスタムIconifyコレクションを作成できます。

例えば、アイコンのSVGファイルを選択したフォルダ(例: ./assets/my-icons)に配置します。

assets/my-icons
├── foo.svg
├── bar-outline.svg

nuxt.config.tsで、icon.customCollectionsに項目を追加します。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons'
      },
    ],
  },
})

!NOTE Nuxt 4で新しいappディレクトリを実行している場合、アセットディレクトリは'./assets/*'ではなく'./app/assets/*'になります。

そして、以下のようにアイコンを使用できます。

<template>
  <Icon name="my-icon:foo" />
  <Icon name="my-icon:bar-outline" />
</template>

完全なカスタムIconifyJSONオブジェクトを渡すこともできます。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'paid-icons',
        icons: {
          'nuxt': { body: '<path d="M281.44 ... />' },
        },
        width: 512,
        height: 512,
      }
    ],
  },
})

カスタムローカルコレクションを使用するには、APIを提供するサーバーが必要です。ssr: falseを設定した場合、またはnuxt generateを使用して静的アプリを生成する場合(これはssr: falseと同等です)、プロバイダーはデフォルトでIconify API(カスタムアイコンは含まれていません)になります。サーバーエンドポイントを持つSPAを構築したい場合は、provider: 'server'を明示的に設定できます。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  ssr: false,
  icon: {
    provider: 'server', // <-- this
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons'
      },
    ],
  },
})

あるいは、動的なアイコンのフェッチを完全に無効にし、クライアントバンドルからのアイコンのみを使用したい場合は、provider: 'none'を設定できます。

export default defineNuxtConfig({
  icon: {
    provider: 'none',
    clientBundle: {
      scan: true,
      // ...or other bundle options
    },
  }
})

大文字と小文字を区別するカスタムコレクション

v1.10より前は、Iconifyの以前の規約の制限により、すべてのカスタムアイコンはkebab-caseに正規化され、警告が表示されていました。Iconify側の更新のおかげで、v1.10以降、大文字と小文字を区別するカスタムコレクションを使用し、正規化をスキップすることを選択できます。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons',
        normalizeIconName: false, // <-- this
      },
    ],
  },
})

これにより、例えばassets/my-icons/FooBar.svgmy-icon:FooBarとして使用できるようになります。

normalizeIconNameは、後方互換性のためにデフォルトでtrueに設定されており、将来のメジャーバージョンで反転されます。詳細については#265を参照してください。

アイコンのカスタマイズ

<Icon />のデフォルトサイズ (1em) を更新するには、icon.sizeプロパティを含むapp.config.tsを作成します。

<Icon />のデフォルトクラス (.icon) をicon.classプロパティで更新します。ヘッドレスアイコンの場合は、icon.class: ''を設定します。

icon.aliasesプロパティを活用することで、アイコンの入れ替えを容易にするエイリアスを定義することもできます。

!NOTE ランタイム設定はnuxt.config.tsではなくapp.config.tsであることに注意してください。

// app.config.ts
export default defineAppConfig({
  icon: {
    size: '24px', // default <Icon> size applied
    class: 'icon', // default <Icon> class applied
    mode: 'css', // default <Icon> mode applied
    aliases: {
      'nuxt': 'logos:nuxt-icon',
    },
    cssLayer: 'base' // set the css layer to inject to
  }
})

アイコンはデフォルトで24pxのサイズになり、nuxtアイコンが利用可能になります。

<Icon name="nuxt" />

デフォルトでは、このモジュールはローカルサーバーバンドルからアイコンを提供するためのサーバーエンドポイント/api/_nuxt_icon/:collectionを作成します(icon.localApiEndpointを目的のパスに設定することで、デフォルトパスを上書きできます)。ローカルバンドルに存在しないアイコンがリクエストされた場合、公式のIconify APIにフォールバックしてリクエストします。icon.fallbackToApifalseに設定することでフォールバックを無効にするか、独自のIconify APIを設定し、icon.iconifyApiEndpointを独自のAPIエンドポイントに更新できます。

customizeオプションによるアイコンのカスタマイズ

カスタマイズオプションを使用すると、プロジェクトで使用されるSVGアイコンのさまざまな側面を変更できます。このオプションでできること

  • ストロークの太さの変更
  • 色の変更
  • アニメーションの持続時間の変更
  • 不透明度の変更
  • 追加の形状の追加

これらのカスタマイズオプションを使用すると、SVGコンテンツを完全に制御できます。

コンポーネント内 コンポーネント内でカスタマイズ関数を定義して、アイコンにさまざまな変更を適用できます。

<script setup lang="ts">
// Define the customize function to modify SVG content
const customize = (content: string, name: string, prefix: string, provider: string) => {
  if (prefix !== 'tabler') return content // Ignore Prefix

  return content
    .replace(/stroke-width="[^"]*"/g, `stroke-width="2"`) // Change stroke width to 2
    .replace(/stroke="[^"]*"/g, `stroke="#FF5733"`) // Change stroke color to red
    .replace(/fill="[^"]*"/g, `fill="#FF5733"`) // Change fill color to red
    .replace(/animation-duration="[^"]*"/g, `animation-duration="1s"`) // Change animation duration to 1s (for animated icons)
    .replace(/opacity="[^"]*"/g, `opacity="0.8"`);// Change opacity to 0.8
}
</script>

<template>
  <Icon name="tabler:star" :customize="customize" />
</template>

<!-- You can also use `:customize="false"` to disabled the global customization function per-usage -->

アプリケーション設定ファイル内

あるいは、app.config.tsファイルでこれらのカスタマイズをグローバルに適用することもできます。

// app.config.ts
export default defineAppConfig({
  icon: {
    customize: (content: string, name: string, prefix: string, provider: string) => {
      // ...
    },
  }
})

この設定により、アプリケーション全体で一貫してこれらのカスタマイズがすべてのアイコンに適用されます。

サーバーバンドル

@nuxt/icon v1.0以降、Nuxtサーバーエンドポイントからアイコンを提供するためのサーバーバンドルの概念を導入しました。これにより、クライアントバンドルを軽量に保ち、オンデマンドでアイコンをロードできると同時に、ビルド時に不明なアイコンを使用するためのすべての動的機能を利用できます。

サーバーバンドルモード: local

このモードでは、ローカルにインストールしたアイコンコレクション(例: @iconify-json/*)を、動的なチャンクとしてサーバーバンドルにバンドルします。コレクションデータは、クライアントがそのコレクションからアイコンをリクエストしたときにのみオンデマンドでロードされます。

サーバーバンドルモード: remote

@nuxt/icon v1.2で導入され、remoteサーバーバンドルを使用してリモートCDNからアイコンを提供できるようになりました。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    serverBundle: 'remote',
  },
})

または、リモートプロバイダーを指定することもできます。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    serverBundle: {
      remote: 'jsdelivr', // 'unpkg' or 'github-raw', or a custom function
    }
  },
})

これにより、サーバーバンドルにアイコンをバンドルする代わりに、ランタイム時にhttps://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.jsonにサーバーリクエストを送信してアイコンをフェッチします。

内部的には、サーバーバンドルに() => import('@iconify-json/ph/icons.json')をバンドルする代わりに、() => fetch('https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json').then(res => res.json())のようなものを使用します。この場合、コレクションはインライン化されません。

これは、サーバーレス環境やワーカー環境のように、サーバーバンドルサイズが懸念される場合に役立ちます。

サーバーバンドルモード: auto

これはデフォルトのオプションで、デプロイ環境に基づいてモジュールがlocalremoteのどちらかを選択します。Vercel EdgeやCloudflare Workersのようなサーバーレスまたはワーカー環境にデプロイしない限り、localが優先されます。

アイコンJSONの外部化

デフォルトでは、Nitroはローカルにインストールされたアイコンコレクション(例: @iconify-json/*)を、動的なチャンクとしてサーバーバンドルにバンドルします。大量のアイコンがある場合、これによりバンドルプロセスが遅くなり、メモリを大量に消費する可能性があります。アイコンJSONファイルを外部化するには、icon.serverBundle.externalizeIconsJsontrueに設定します。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    serverBundle: {
      externalizeIconsJson: true,
    }
  },
})

これは、本番のNode.jsサーバーがJSONファイルをインポートできる必要があることに注意してください(Node.js v22の時点では、JSONモジュールはまだ実験的な機能です)。最終ビルドでは、() => import('@iconify-json/ph/icons.json', { with: { type: 'json' } })のようなステートメントが含まれます。

また、Cloudflare Workersのような動的なインポートがない一部のサーバーレス環境では、このオプションに関係なく常にインライン化されることに注意してください。

このオプションは、icon.serverBundle.remoteが有効な場合は無視されます。

サーバーバンドルを完全に無効にする

サーバーバンドルを完全に無効にしたい場合は、icon.serverBundlefalseに、providericonifyに設定できます。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    provider: 'iconify',
    serverBundle: false,
  },
})

これにより、クライアントがアイコンを要求するたびにIconify APIへのリクエストが発生します。他のオプションが実現不可能な場合を除き、これを行うことはお勧めしません。

クライアントバンドル

頻繁に使用することがわかっているアイコンについては、ネットワークリクエストを避けるためにクライアントバンドルに含めることができます。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    clientBundle: {
      // list of icons to include in the client bundle
      icons: [
        'uil:github',
        'logos:vitejs'
      ],

      // scan all components in the project and include icons 
      scan: true,

      // include all custom collections in the client bundle
      includeCustomCollections: true, 

      // guard for uncompressed bundle size, will fail the build if exceeds
      sizeLimitKb: 256,
    },
  },
})

includeCustomCollectionsは、icon.customCollectionsで定義したすべてのカスタムコレクションをクライアントバンドルに含めます。デフォルトでは無効になっていますが、ssr: falseが設定されている場合は自動的に有効になります。

コンポーネントをスキャンする

scanが有効な場合、モジュールはプロジェクト内のすべてのコンポーネントをスキャンし、使用されているアイコンをクライアントバンドルに含めます。これにより、静的に既知のアイコンに必要なネットワークリクエストの数を大幅に減らすことができますが、プロジェクトで使用されるアイコンの数によってはクライアントバンドルサイズが増加する可能性があります。

スキャンターゲットを以下のように微調整することもできます。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    clientBundle: {
      scan: {
        // note that when you specify those values, the default behavior will be overridden
        globInclude: ['components/**/*.vue', /* ... */],
        globExclude: ['node_modules', 'dist', /* ... */],
      },
    },
  },
})

!TIP スキャンは静的解析に依存しているため、リテラルな使用のみが検出されます。可能であれば、アイコン名を動的に構築することを避けてください。

<template>
  <!-- Avoid this -->
  <Icon :name="`carbon:${dark ? 'moon' : 'sun'}`" />

  <!-- Prefer this -->
  <Icon :name="dark ? 'carbon:moon' : 'carbon:sun'" />
</template>

レンダリング関数

レンダリング関数でIconコンポーネントを使用できます(機能コンポーネントを作成する場合に便利です)。このために、#componentsからインポートできます。

import { Icon } from '#components'

<MyIcon>コンポーネントの例をご覧ください。

<script setup>
import { Icon } from '#components'

const MyIcon = h(Icon, { name: 'uil:twitter' })
</script>

<template>
  <p><MyIcon /></p>
</template>

貢献 🙏

  1. このリポジトリをクローンする
  2. pnpm installを使用して依存関係をインストールします(corepack enablepnpmをインストールします。詳細はこちら
  3. 型スタブを生成するには、npm run dev:prepareを実行してください。
  4. npm run devを使用して、開発モードでプレイグラウンドを開始します。

クレジット 💌

ライセンス 📎

MITライセンス