Nuxt 2 is reaching End-of-Life on June 30th, 2024.

icon-tw
icon-tw

Extended Icon module with Tailwind CSS Icons for Nuxt

nuxt-icon-tw

Nuxt Icon Tailwind

npm version npm downloads License Nuxt

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

Uses Tailwind CSS Icons to load locally rather than via API calls for each icon

Can add custom collections from JSON files in addition to locally installed Iconify packages

Falls back to API calls for collections not loaded locally

Features ✨

  • Tailwind CSS Icons via Iconify JSON packages
  • Custom local IconCollection JSON files
  • Nuxt 3 ready
  • Support 100,000 open source vector icons via Iconify
  • Emoji Support
  • Custom SVG support (via Vue component)

Setup ⛓️

Add nuxt-icon-tw dependency to your project (it does require Tailwind of course):

npx nuxi@latest module add icon-tw
npx nuxi@latest module add tailwindcss

Add it to the modules array in your nuxt.config.ts:

import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
  modules: ['nuxt-icon-tw', '@nuxtjs/tailwindcss'],
})

Install any Iconify JSON packages you want to use via Tailwind CSS:

npm install --save-dev @iconify-json/mdi

# Using yarn
yarn add --dev @iconify-jsom/mdi

These will be picked up automatically by the Tailwind CSS plugin.

<Icon /> will use Tailwind to load any icons starting with i-prefix ie i-mdi-home. If you use i-other-icon and it is a set not installed locally, the icon will fallback to Iconify API SVG loading

Any icons using a : divider (ie i-mdi:home or mdi:home) will remain Iconify SVG since Tailwind does not allow : in classes.

This allows for NuxtIconTw to be a drop in replacement for NuxtIcon if you want to add Tailwind Icons to an existing project (incidentally, this is why I created this)

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

Usage 👌

Props:

  • name (required): icon name, emoji or global component name
  • size: icon size (default: 1em)

Attributes:

When using an icon from Iconify, an <svg> will be created, you can give all the attributes of the native element.

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

Other Components::

  • <Icon /> - Automatically set to Tailwind or Iconify SVG based on loaded collections
  • <IconTw /> - Only creates icon by Tailwind - if the name specified is not loaded, it will be blank
  • <IconSvg /> - Only creates icon by Iconify Svg - but custom files will not work here

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).

Custom Icon Collections

You can specify locations of custom icon JSON files to have them included in the Tailwind CSS:

import { createResolver } from '@nuxt/kit'

const { resolve } = createResolver(import.meta.url)

export default defineNuxtConfig({
  icon: {
    customCollections: resolve('./custom.json'),
  },
  modules: ['nuxt-icon-tw', '@nuxtjs/tailwindcss'],
})

Note you can also get these to show up in VS Code Iconify

{
  // set from root of the project
  "iconify.customCollectionJsonPaths": ["./playground/custom.json"]
}

Emoji

<Icon name="🚀" />

Vue component

<Icon name="NuxtIcon" />

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

Tailwind Icons Configuration

Prefix

You can specify what prefix you want to use on Tailwind Icons classes. This defaults to i for backwards compatibility with other Tailwind Icons plugins. However, it can be set empty ('') to not require a prefix at all.

Collections

Specify the Iconify sets you wish to include

  • string[]:
    export default defineNuxtConfig({
      icon: {
        collections: ['mdi', 'ph'],
      },
      modules: ['nuxt-icon-tw', '@nuxtjs/tailwindcss'],
    })
    
  • []: turn off automated resolution altogether
  • 'all': specifically opt in to loading the full Iconify JSON; warning: can be slow
  • IconCollection: entirely override the automation
    export default defineNuxtConfig({
      icon: {
        collections: {
          foo: {
            icons: {
              'arrow-left': {
                body: '<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"/>',
                width: 20,
                height: 20,
              },
            },
          },
        },
      },
      modules: ['nuxt-icon-tw', '@nuxtjs/tailwindcss'],
    })
    

Force Tailwind

If you should want to only allow Tailwind Icons and no Iconify API icons at all, set this to true.

export default defineNuxtConfig({
  icon: {
    forceTailwind: true,
  },
  modules: ['nuxt-icon-tw', '@nuxtjs/tailwindcss'],
})

Configuration ⚙️

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

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

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

// app.config.ts
export default defineAppConfig({
  nuxtIcon: {
    size: '24px', // default <Icon> size applied
    class: 'icon', // default <Icon> class 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 fetch the Icons from the official Iconify API. You can change this behavior by setting the nuxtIcon.iconifyApiOptions.url property to your own Iconify API.

You can also set nuxtIcon.iconifyApiOptions.publicApiFallback to true to use the public API as a fallback (only for the <Icon> component, not for the <IconCSS> component`)

// app.config.ts
export default defineAppConfig({
  nuxtIcon: {
    // ...
    iconifyApiOptions: {
      url: 'https://<your-api-url>',
      publicApiFallback: true, // default: false
    },
  },
})

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