Skip to content

nuxt/icon

Repository files navigation

nuxt-icon

Nuxt Icon

npm version npm downloads License Nuxt Volta board

Add 200,000+ ready to use icons to your Nuxt application, based on Iconify.

Features ✨

  • Nuxt 3 ready
  • SSR friendly
  • Support 200,000 open-source vector icons via Iconify
  • Support both CSS mode / SVG mode
  • Custom SVG support (via Vue component, or via local SVG files)

Note

You are viewing the v1.0 version of this module, which is a complete rewrite for a better developer experience and performance. If you are migrating from v0.6, please check this PR for the full list of changes.

Setup ⛓️

Run the following command to add the module to your project:

npx nuxi module add icon

That's it, you can now use the <Icon /> in your components!

✨ If you are using VS Code, you can use the Iconify IntelliSense extension by @antfu

Manual Setup

You can install the module manually with:

npm i -D @nuxt/icon

Update your nuxt.config.ts

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

If you have the legacy module nuxt-icon installed, you might want to remove it from the modules list.

Usage 👌

Props:

  • name (required): icon name or global component name
  • size: icon size (default: 1em)
  • mode: icon rendering mode (svg or css, default: css)

Attributes:

When using an icon from Iconify, an <span> or <svg> will be created based on the rendering mode, you can give all the attributes of the native element.

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

Iconify Dataset

You can use any name from the https://icones.js.org collection:

<Icon name="uil:github" />

It supports the i- prefix (for example, i-uil-github).

It's highly recommended to install the icon data locally with

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

For example, to use the uil:github icon, install it's collection with @iconify-json/uil. This way the icons can be served locally or from your serverless functions, which is faster and more reliable on both SSR and client-side.

Vue Component

When the name matches a global registered component, it will be rendered as that component (in this case mode will be ignored):

<Icon name="MyComponent" />

Note that MyComponent needs to be inside components/global/ folder (see example).

Tip

You can also change the component name with:

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

Custom Local Collections

You can use local SVG files to create a custom Iconify collection.

For example, place your icons' SVG files under a folder of your choice, for example, ./assets/my-icons:

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

In your nuxt.config.ts, add an item in icon.customCollections:

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

Then you can use the icons like this:

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

Note that custom local collections require you to have a server to serve the API. When setting ssr: false, the provider will default to the Iconify API (which does not have your custom icons). If you want to build a SPA with server endpoints, you can explicitly set provider: 'server':

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

Icon Customization

To update the default size (1em) of the <Icon />, create an app.config.ts with the icon.size property.

Update the default class (.icon) of the <Icon /> with the icon.class property, for a headless Icon, set icon.class: ''`.

You can also define aliases to make swapping out icons easier by leveraging the icon.aliases property.

Note

Note it's app.config.ts and not nuxt.config.ts for runtime configs.

// 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',
    }
  }
})

The icons will have the default size of 24px and the nuxt icon will be available:

<Icon name="nuxt" />

By default, this module will create a server endpoint /api/_nuxt_icon/:collection to serve the icons from your local server bundle (you can override the default path by setting icon.localApiEndpoint to your desired path). When requesting an icon that does not exist in the local bundle, it will fallback to requesting the official Iconify API. You can disable the fallback by setting icon.fallbackToApi to false, or set up your own Iconify API and update icon.iconifyApiEndpoint to your own API endpoint.

Server Bundle

Since @nuxt/icon v1.0, we have introduced the server bundle concept to serve the icons from Nuxt server endpoints. This keeps the client bundle lean and able to load icons on-demand, while having all the dynamic features to use icons that might now be known at build time.

Server Bundle Mode: local

This mode will bundle the icon collections you have installed locally (like @iconify-json/*), into your server bundle as dynamic chunks. The collection data will be loaded on-demand, only when your client request icons from that collection.

Server Bundle Mode: remote

Introduced in @nuxt/icon v1.2, you can now use the remote server bundle to serve the icons from a remote CDN.

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

Or you can specify the remote provider:

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

Which will make server requests to https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json to fetch the icons at runtime, instead of bundling them with your server.

Under the hood, instead of bundling () => import('@iconify-json/ph/icons.json') to your server bundle, it will now use something like () => fetch('https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json').then(res => res.json()), where the collections are not inlined.

This would be useful when server bundle size is a concern, like in serverless or worker environments.

Server Bundle Mode: auto

This is the default option, where the module will pick between local and remote based your deployment environment. local will be proffered unless you are deploying to a serverless or worker environment, like Vercel Edge or Cloudflare Workers.

Completely Disable Server Bundle

If you want to disable the server bundle completely, you can set icon.serverBundle to false and provider to iconify

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

This will make requests to Iconify API every time the client requests an icon. We do not recommend doing so unless the other options are not feasible.

Client Bundle

For icons that you know you are going to use frequently, you can bundle them with your client bundle to avoid network requests.

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    clientBundle: {
      icons: [
        'uil:github',
        'logos:vitejs'
      ],
    },
  },
})

Currently, this is a manual config process, we are working on making it more automatic and easier to use.

Render Function

You can use the Icon component in a render function (useful if you create a functional component), for this you can import it from #components:

import { Icon } from '#components'

See an example of a <MyIcon> component:

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

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

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

Contributing 🙏

  1. Clone this repository
  2. Install dependencies using pnpm install (install pnpm with corepack enable, learn more)
  3. Run npm run dev:prepare to generate type stubs.
  4. Use npm run dev to start playground in development mode.

Credits 💌

License 📎

MIT License