Access thousands of icons as components on-demand universally across multiple build tools and frameworks
—
Custom icon loading functionality for filesystem icons, external packages, and custom icon sources.
Load icons from a filesystem directory with optional SVG transformation.
/**
* Creates a custom icon loader for filesystem icons
* @param dir - Directory path containing SVG files
* @param transform - Optional SVG transformation function
* @returns CustomIconLoader function
*/
function FileSystemIconLoader(
dir: string,
transform?: (svg: string) => Awaitable<string>
): CustomIconLoader;Usage Examples:
import { FileSystemIconLoader } from "unplugin-icons/loaders";
import Icons from "unplugin-icons/vite";
export default {
plugins: [
Icons({
customCollections: {
// Basic filesystem loader
'local': FileSystemIconLoader('./src/assets/icons'),
// With SVG transformation
'branded': FileSystemIconLoader(
'./src/assets/brand-icons',
(svg) => svg.replace(/^<svg /, '<svg fill="currentColor" ')
),
// With async transformation
'processed': FileSystemIconLoader(
'./src/assets/raw-icons',
async (svg) => {
// Custom processing logic
return svg
.replace(/fill="[^"]*"/g, '') // Remove existing fills
.replace(/^<svg/, '<svg fill="currentColor"'); // Add currentColor
}
),
},
}),
],
};Load icons from external npm packages with optional auto-installation.
/**
* Creates custom icon loaders for external packages
* @param packageName - Name of the external package containing icons
* @param autoInstall - Auto-installation configuration
* @returns Record of collection names to CustomIconLoader functions
*/
function ExternalPackageIconLoader(
packageName: ExternalPkgName,
autoInstall?: AutoInstall
): Record<string, CustomIconLoader>;Usage Examples:
import { ExternalPackageIconLoader } from "unplugin-icons/loaders";
import Icons from "unplugin-icons/vite";
export default {
plugins: [
Icons({
customCollections: {
// Load from external package
...ExternalPackageIconLoader("@my-company/icon-package"),
// With auto-install
...ExternalPackageIconLoader(
"@iconscout/unicons",
{ autoInstall: true }
),
},
}),
],
};The function signature for custom icon loaders.
/**
* Custom icon loader function signature
* @param name - Icon name to load
* @returns Promise resolving to SVG string or undefined if not found
*/
type CustomIconLoader = (name: string) => Awaitable<string | undefined>;Define icons directly in configuration using inline collections.
/**
* Inline collection of icons defined as strings or functions
*/
type InlineCollection = Record<string, string | (() => Awaitable<string | undefined>)>;Usage Examples:
import Icons from "unplugin-icons/vite";
export default {
plugins: [
Icons({
customCollections: {
// Static inline icons
'ui': {
'check': '<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>',
'close': '<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>',
},
// Dynamic inline icons
'dynamic': {
'star': () => fetch('/api/icon/star').then(r => r.text()),
'heart': async () => {
const response = await fetch('/api/icon/heart');
return response.text();
},
},
},
}),
],
};import { FileSystemIconLoader, ExternalPackageIconLoader } from "unplugin-icons/loaders";
import Icons from "unplugin-icons/vite";
export default {
plugins: [
Icons({
customCollections: {
// Combine different loading strategies
'brand': FileSystemIconLoader('./assets/brand'),
'ui': FileSystemIconLoader('./assets/ui', svg =>
svg.replace(/stroke="[^"]*"/g, 'stroke="currentColor"')
),
...ExternalPackageIconLoader("@company/icons"),
// Fallback/override system
'icons': {
// High priority inline icons
'logo': '<svg>...</svg>',
'special': async () => {
try {
return await fetch('/api/special-icon').then(r => r.text());
} catch {
// Fallback to filesystem
return FileSystemIconLoader('./fallbacks')('special');
}
},
},
},
}),
],
};import { FileSystemIconLoader } from "unplugin-icons/loaders";
// Create reusable transformation functions
const addCurrentColor = (svg: string) =>
svg.replace(/fill="(?!none)[^"]*"/g, 'fill="currentColor"');
const addViewBox = (svg: string) =>
svg.includes('viewBox') ? svg : svg.replace('<svg', '<svg viewBox="0 0 24 24"');
const transformPipeline = (svg: string) => addViewBox(addCurrentColor(svg));
export default {
plugins: [
Icons({
customCollections: {
'icons': FileSystemIconLoader('./src/icons', transformPipeline),
},
}),
],
};import Icons from "unplugin-icons/vite";
// Function to create dynamic collections
const createDynamicCollection = (apiEndpoint: string): InlineCollection => ({
async load(name: string) {
try {
const response = await fetch(`${apiEndpoint}/${name}.svg`);
return response.ok ? response.text() : undefined;
} catch {
return undefined;
}
},
});
export default {
plugins: [
Icons({
customCollections: {
'remote': createDynamicCollection('https://api.example.com/icons'),
},
}),
],
};Install with Tessl CLI
npx tessl i tessl/npm-unplugin-icons