notes.dt.in.th

Using the Iconify Icon Web Component

The Iconify Icon Web Component let you render icons from any icon set (as well as custom icons) in any web framework (or without any framework).

This is something that I’ve been waiting for a long time.

Note

The Iconify project has a pretty large API surface area for flexibility and legacy purposes1. This note describes my recommended way to use them, which is to use the Iconify Icon Web Component.

This note covers the steps for React and Next.js. Vue and Svelte already have excellent support for Web Components, and you should be able to use them with ease.

Usage with React

Here’s how I use Iconify with React:

  1. Install the @iconify-icon/react package and the icon sets. (Browse the icon sets)

    • Do not confuse this with the older @iconify/react package.2
  2. When you want to use an icon, import the Icon component and the icon you want to use:

    import { Icon } from '@iconify-icon/react'
    import githubIcon from '@iconify-icons/codicon/github'
    
    function MyComponent() {
      return <Icon icon={githubIcon} />
    }
    • If you want, you can also skip installing the icon sets in your project and use the icons directly from Iconify’s CDN.^[I prefer self-hosting, though.]

      function MyComponent() {
        return <Icon icon="codicon:github" />
      }

Usage with Next.js

You can follow the steps above, but the icons will not appear until the page is hydrated. This is because the icons are rendered with the <iconify-icon> web component, which is not initialized until the page is hydrated.

If you want the icons to appear immediately, you can follow these steps to sideload the web component script (so they are loaded and initialized independently of the Next.js app):

  1. Add the Iconify web component script to your pages/_document.tsx:

    import { Html, Head, Main, NextScript } from 'next/document'
    
    export default function Document(props: any) {
      return (
        <Html>
          <Head>
            <script
              async
              src="https://cdn.jsdelivr.net/npm/iconify-icon@1.0.7/dist/iconify-icon.min.js"
              integrity="sha256-B/ef37ds8F6TYyf8o9fLmpoxxXe1Tm2cO30jGN5hhRA="
              crossOrigin="anonymous"
            />
          </Head>
          <body>
            <Main />
            <NextScript />
          </body>
        </Html>
      )
    }

    (Check latest version on jsDelivr here)

  2. Install the react-iconify-icon-wrapper package and the icon sets. (Browse the icon sets)

    • This package is almost identical to the @iconify-icon/react package. The difference is that it does not bundle the web component script, so you can sideload it instead.
  3. When you want to use an icon, import the Icon component and the icon you want to use:

    import { Icon } from 'react-iconify-icon-wrapper'
    import githubIcon from '@iconify-icons/codicon/github'
    
    function MyComponent() {
      return <Icon icon={githubIcon} />
    }

Footnotes

  1. Iconify is available as a Web Component (with wrappers for React and Solid), vanilla JS library, a React component, a Vue 3 component, a Vue 2 component, a Svelte component, and an Ember component. Additionally, the Iconify project provides an API for generating SVG to be used in plain CSS. And there are 3rd party integrations for unplugin, UnoCSS, Astro, and the list goes on and on.

    However, with the advent of the Iconify Icon Web Component, I think we now have one solution to rule them all.

  2. There are 2 packages:

    • @iconify/react is the older library which implements the component directly in React. It is now recommended to use @iconify-icon/react instead.
    • @iconify-icon/react is the newer library which is a simple React wrapper that renders the <iconify-icon> web component under the hood.