Iconify Icon web component
Iconify Icon is a web component renders icons.
Usage
It is designed to be as easy to use as possible.
<iconify-icon icon="mdi:home"></iconify-icon>
Supported frameworks
Web component can be used in HTML without any UI framework. See usage examples below.
It also works great with all modern frameworks that support web components:
- Svelte and SvelteKit/Sapper.
- Vue 2 and Vue 3. Require changing config when used in Nuxt (see below).
- Lit.
- Ember.
- React and Next, but with small differences, such as using class instead of className. Wrapper fixes it.
However, some UI frameworks require custom wrappers:
- Solid. See Iconify icon web component for Solid.
Layout shift
Web component is not rendered instantly. There could be a few milliseconds delay.
This is caused by:
- JavaScript. Web component cannot be rendered until it is loaded and registered.
- Because of web component spec. Rendering is done asynchronously in browser, often causing tiny delay.
This might cause layout shift.
To avoid layout shift, add this to your CSS:
iconify-icon {
display: inline-block;
width: 1em;
height: 1em;
}
Icon data on demand
Instead of embedding an entire icon, all you need to do is provide an icon name in icon attribute.
Web component will retrieve icon data from Iconify API, then will render SVG in shadow DOM.
There are over 200k icons available from many open source icon sets.
Don't want to rely on third party API servers? You can host your own Iconify API. You can also use it with your own icons.
Shadow DOM
SVG is rendered in shadow DOM. What does that mean?
- HTML for icon is hidden, not part of the main document.
- It simplifies hydration when the web component is used in a UI framework with server side rendering. See below.
- Stylesheet used in the document does not affect icons, preventing potential conflicts.
Sometimes this can be a disadvantage, for example, if you do want to access icon content to perform CSS or JavaScript based animations. If you do not want a web component that uses shadow DOM, take a look at Iconify icon components.
SSR hydration
One of the issues a web component solves is a hydration, which is used by many modern UI frameworks.
Server side rendering is becoming more and more popular, hydration is complex and can easily be broken by a mismatched DOM.
What is hydration? Hydration is a process of matching content generated on server and content generated by UI framework in browser. Instead of re-rendering document, a UI framework uses HTML generated on server. This is the basic explanation. It is actually more complex than that, see various articles on SSR hydration.
There are several issues with hydrating icons:
- Icons might have unique IDs in elements, such as masks and clip paths. Using multiple icons on the same page requires using different IDs (or randomising them), which usually breaks hydration process.
- Dynamically loaded icon data cannot be rendered before hydration ends. This can be solved by rendering icon only after component has been mounted, but that might cause rendering delays and other issues.
Shadow DOM used by web components solves hydration problems. When a UI framework renders icon on server, it only renders <iconify-icon> element. During hydration process, UI framework only checks <iconify-icon> element, but not actual icon. This means:
- Server side can generate only <iconify-icon icon="mdi:home"></iconify-icon>, reducing document size.
- Web component can load icon data and render it immediately and independent of a UI framework, not waiting for a UI framework to mount the component.
- No issues with duplicate unique IDs. Each icon has its own document, so no need to change IDs of icon elements.
- Faster hydration. Icons can be complex, not checking icon content means less work for a UI framework.
Using shadow DOM to render icon leads to better experience for developers. No need to configure anything, no need to worry about icon data, no need to worry about conflicts. It just works.
Rendering only visible icons
As of version 2.0.0 of the web component, icons are rendered only when visible to the visitor.
For long documents with many icons, this improves the performance of pages by a lot.
As of version 2.1.0, you can opt out of this behavior by adding noobserver attribute to web component's HTML:
<iconify-icon icon="mdi:home" noobserver></iconify-icon>
Why not use icon font?
Shadow DOM used by web component has big advantages over usual SVGs or framework specific components, but what about icon fonts?
Do not use icon fonts!!!
- Icon fonts are ugly. Browser renders icons using font rendering methods, which causes blurred icon edges and icons lose their sharpness.
- Icons rendered from icon fonts are often hard to align, resulting in misaligned icons.
- Browsers load huge fonts just to render few icons. This can be solved by using custom icon fonts, but doesn't solve other issues.
- No colored icons, only monotone. No SVG animations.
Icon fonts do not belong in modern web. They were a great solution when Internet Explorer was popular, web components did not exist and SVG support was buggy. Those bad times are over.
Registering the web component
For the web component to work, it needs to be registered. iconify-icon package does that automatically. All you need to do is include it on a page.
If you are building a project with a bundler, you can include the script by installing iconify-icon as a dependency and importing it in your project:
import 'iconify-icon';
If you are not using bundles or want icon web component to be imported separately, add script to your document:
<script src="https://code.iconify.design/iconify-icon/2.1.0/iconify-icon.min.js"></script>
or
<script src="https://cdn.jsdelivr.net/npm/iconify-icon@2.1.0/dist/iconify-icon.min.js"></script>
Nuxt
When using component with Nuxt, you need to tell it that <iconify-icon> is a web component.
Example of nuxt.config.ts:
import { defineNuxtConfig } from 'nuxt3';
export default defineNuxtConfig({
vue: {
compilerOptions: {
isCustomElement: (tag) => tag === 'iconify-icon',
},
},
});
Attributes
There are several attributes to customise icon appearance.
To change color (color can be changed only for monotone icons) or size, use style:
<iconify-icon
icon="mdi:alert"
style="color: #ba3329; font-size: 48px"
></iconify-icon>
You can also change size using width and/or height attributes:
All icons below are 36x36:
<p>All icons below are 36x36:</p>
<iconify-icon icon="cil:locomotive" height="36"></iconify-icon>
<iconify-icon icon="cil:paper-plane" width="36"></iconify-icon>
<iconify-icon
icon="cil:truck"
style="font-size: 18px"
height="2em"
></iconify-icon>
If only one size attribute is set, another attribute is calculated using icon's width/height ratio.
You can also transform icon. Unlike CSS transformations, these transformations are done inside icon, which also affects icon's viewBox:
No transformations:
Horizontal flip:
Vertical flip:
Horizontal and vertical flip (same as 180° rotation):
90° rotation:
180° rotation:
270° rotation:
<p>No transformations: <iconify-icon icon="bi:check2-circle"></iconify-icon></p>
<p>
Horizontal flip:
<iconify-icon icon="bi:check2-circle" flip="horizontal"></iconify-icon>
</p>
<p>
Vertical flip:
<iconify-icon icon="bi:check2-circle" flip="vertical"></iconify-icon>
</p>
<p>
Horizontal and vertical flip (same as 180° rotation):
<iconify-icon
icon="bi:check2-circle"
flip="horizontal,vertical"
></iconify-icon>
</p>
<p>
90° rotation:
<iconify-icon icon="bi:check2-circle" rotate="90deg"></iconify-icon>
</p>
<p>
180° rotation:
<iconify-icon icon="bi:check2-circle" rotate="180deg"></iconify-icon>
</p>
<p>
270° rotation:
<iconify-icon icon="bi:check2-circle" rotate="270deg"></iconify-icon>
</p>
Attributes list
All attributes are also available as properties, so you can access them easy in JavaScript when working with elements.
Required attribute:
- icon, IconifyIcon|string icon name or icon data. Because attributes can only be strings, if you want to provide IconifyIcon data, you need to either use property or JSON.stringify() it. See icon data.
Optional attributes:
- mode, string sets icon rendering mode. See rendering modes.
- inline, boolean changes vertical alignment. See vertical alignment.
- width, string|number icon width. See icon dimensions.
- height, string|number icon height. See icon dimensions.
- flip, string flip icon. See icon transformations.
- rotate, number|string rotates icon. See icon transformations.
Functions
For advanced developers, web component offers several functions to control it.
These functions can be used to load custom icons, get icon data, preload icons from API, configure custom API and so on. See functions list below.
Functions can be imported from:
- iconify-icon package, which also bundles web component. Usable in browser and Node.js.
- Web component class as static methods, which is available after component is registered.
- <iconify-icon> node as methods, which are available after component is registered and new elements are created.
First method is the most reliable because it is a simple import. It is used in all examples:
import { loadIcon } from 'iconify-icon';
const name = 'mdi:home';
loadIcon(name)
.then((data) => {
console.log('Loaded data for', name);
})
.catch(console.error);
For second method, class can be retrieved from custom elements' registry:
const IconifyIcon = window.customElements.get('iconify-icon');
const name = 'mdi:home';
IconifyIcon.loadIcon(name)
.then((data) => {
console.log('Loaded data for', name);
})
.catch(console.error);
Third method can be used after creating a new icon element or accessing an existing element:
const IconifyIcon = document.createElement('iconify-icon');
const name = 'mdi:home';
IconifyIcon.loadIcon(name)
.then((data) => {
console.log('Loaded data for', name);
})
.catch(console.error);
Functions are split in several groups (click function name to see more details and examples):
Instance functions
These functions are available only on web component nodes:
- restartAnimation(). Restarts SVG animation, useful if you want to restart animation on hover event, as shown in right side navigation of this website.
Check available icons
There are several functions in this section:
- iconExists(name). Checks if icon data is available, returns boolean.
- listIcons(). Lists available icons, returns string[].
- getIcon(name). Returns icon data, returns IconifyIcon object.
Adding icons
Functions for adding icons to the component:
- addIcon(). Adds one icon.
- addCollection(). Adds an icon set.
Note: icons added to the component with these functions are not stored in the icon data cache. Component caches only icons retrieved from API.
Helper functions
- calculateSize(). Calculates icon size. It is used to calculate width if only height is set and vice versa.
- buildIcon(icon, customisations?). Generates data used by icon component. This can be used if you prefer to generate <svg> yourself. Data includes attributes for <svg> and inner HTML.
API functions
- loadIcons(icons, callback?). Loads icons from API, calls optional callback when either all or part of icons have been loaded.
- loadIcon(icon). Loads one icon from API, returns Promise.
- enableCache(). Enables caching in localStorage and sessionStorage.
- disableCache(). Disables caching in localStorage and sessionStorage.
- addAPIProvider(). Adds custom API provider. See API providers documentation.
Internal API functions
There are several internal API functions that are exposed. They are intended to be used by developers that need more control over the component. For example, it is used in Sketch and Figma plug-ins. Use them carefully.
All internal API functions are exposed as properties of _api object:
- getAPI(). Returns internal API module.
- getAPIConfig(). Returns API configuration.
- setAPIModule(provider). Sets API module for provider. This is an experimental function intended for custom API providers that use custom module for retrieving data from API.
- setFetch(fetch). Set custom Fetch API.
- getFetch(). Returns used fetch() function, null if Fetch API is not available.