Nuxt Nation カンファレンスが開催されます。11 月 12 ~ 13 日にご参加ください。

icon
@nuxt/icon

Nuxt 用アイコンモジュールで、Iconify から使用可能な 200,000 種類を超えるアイコンに対応しています。

nuxt-icon

Nuxt アイコン

npm versionnpm downloadsLicenseNuxtVolta board

200,000 種類を超える使用可能なアイコン を、Iconify に基づいて Nuxt アプリケーションに追加します。

機能 ✨

  • Nuxt 3 対応
  • SSR 対応
  • Iconify 経由で、200,000 種類を超えるオープンソースのベクターアイコンに対応しています。
  • CSS モードと SVG モードの両方に対応しています。
  • カスタム SVG のサポート(Vue コンポーネントまたはローカルの SVG ファイル経由)

!注意 このモジュールの v1.0 バージョンをご覧になっています。これは、開発者エクスペリエンスとパフォーマンスを向上させるために完全に書き直されたものです. v0.6 から移行する場合は、変更点の全リストについて この PR を参照してください。

設定 ⛓️

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

npx nuxi module add icon

これで、 <Icon /> をコンポーネントで使用できます。

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

手動設定

次のコマンドを使用してモジュールを手動でインストールできます。

npm i -D @nuxt/icon

nuxt.config.ts を更新します。

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

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

使い方 👌

Props

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

属性:

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

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

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とクライアント側のどちらでも高速で信頼性の高い、ローカルまたはサーバーレス関数からアイコンが提供されます。

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

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

Vueコンポーネント

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

<Icon name="MyComponent" />

MyComponentcomponents/global/フォルダ内にある必要があります(を参照してください)。

!ヒントコンポーネント名を次のように変更することもできます。

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

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

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

たとえば、アイコンのSVGファイルを、./assets/my-iconsなどの任意のフォルダに配置します。

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

nuxt.config.tsicon.customCollectionsでアイテムを追加します。

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

次に、次のようにアイコンを使用できます。

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

カスタムローカルコレクションを使用するには、APIを提供するサーバーが必要です。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'
      },
    ],
  },
})

アイコンのカスタマイズ

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

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

icon.aliasesプロパティを活用して、アイコンの差し替えを簡単にするエイリアスを定義することもできます。

!注意ランタイム構成の場合は、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',
    }
  }
})

アイコンのデフォルトサイズは24pxになり、nuxtアイコンが使用できるようになります。

<Icon name="nuxt" />

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

カスタマイズオプションを使用したアイコンのカスタマイズ

カスタマイズオプションを使用すると、プロジェクトで使用される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>

アプリ構成ファイルで

また、これらのカスタマイズを 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 で導入された、アイコンをリモート CDN から提供するための remote サーバーバンドルを、今後使用できるようになります。

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 を使用して依存関係をインストールします (pnpmcorepack enable でインストールします。詳細)
  3. npm run dev:prepare を実行して、タイプスタブを生成します。
  4. npm run dev を使用して、playground を開発モードで開始します。

クレジット 💌

ライセンス 📎

MIT ライセンス