React component for rendering SVG icons from the Iconify ecosystem with over 200,000 icons from 150+ icon sets.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Specialized components and functions for offline icon usage without API dependencies. The offline version provides the same React components but with local storage only, eliminating network requests and providing faster, more predictable performance.
// Import from offline sub-package
import { Icon, InlineIcon, addIcon, addCollection } from "@iconify/react/offline";Block-level icon component optimized for offline usage with memoization for better performance.
/**
* Offline block icon component with middle vertical alignment
* Memoized for optimal performance with pre-loaded icons
* @param props - Icon properties including icon data/name and customizations
* @param ref - Forward ref to the rendered SVG or span element
*/
const Icon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<IconElement>>;Usage Examples:
import { Icon, addIcon } from "@iconify/react/offline";
// Add icon first
const starIcon = {
body: '<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>',
width: 24,
height: 24
};
addIcon("star", starIcon);
// Use icon by name
<Icon icon="star" />
// Use icon data directly
<Icon icon={starIcon} />
// With customizations (same as online version)
<Icon
icon="star"
width="32"
height="32"
color="gold"
rotate={1}
/>Inline icon component optimized for offline usage with memoization.
/**
* Offline inline icon component with baseline vertical alignment
* Memoized for optimal performance with pre-loaded icons
* @param props - Icon properties including icon data/name and customizations
* @param ref - Forward ref to the rendered SVG or span element
*/
const InlineIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<IconElement>>;Usage Examples:
import { InlineIcon, addIcon } from "@iconify/react/offline";
// Add icons first
addIcon("heart", heartIconData);
addIcon("star", starIconData);
// Use in text
<p>
Rate this: <InlineIcon icon="star" color="gold" />
<InlineIcon icon="heart" color="red" />
</p>
// In buttons
<button>
<InlineIcon icon="star" /> Add to Favorites
</button>Add a single icon to offline storage for use by name.
/**
* Add single icon to offline storage
* @param name - Icon name to use when referencing the icon
* @param data - Icon data containing SVG and metadata
*/
function addIcon(name: string, data: IconifyIcon): void;Usage Examples:
import { addIcon } from "@iconify/react/offline";
// Add custom icon
const customIcon = {
body: '<circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/>',
width: 24,
height: 24
};
addIcon("smiley", customIcon);
// Add with namespace
addIcon("ui:close", {
body: '<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"/>',
width: 24,
height: 24
});
// Now use: <Icon icon="smiley" /> or <Icon icon="ui:close" />Add multiple icons from a collection to offline storage with flexible prefix handling.
/**
* Add icon collection to offline storage
* @param data - Icon collection data with prefix and icons
* @param prefix - Optional custom prefix (string) or use collection prefix (true/undefined) or no prefix (false)
*/
function addCollection(data: IconifyJSON, prefix?: string | boolean): void;Usage Examples:
import { addCollection } from "@iconify/react/offline";
// Add collection with its own prefix
const uiIcons = {
prefix: "ui",
icons: {
close: {
body: '<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"/>',
},
check: {
body: '<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>',
},
menu: {
body: '<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>',
}
},
width: 24,
height: 24
};
// Use collection prefix (default behavior)
addCollection(uiIcons);
// Icons available as: "ui:close", "ui:check", "ui:menu"
// Use custom prefix
addCollection(uiIcons, "my-ui-");
// Icons available as: "my-ui-close", "my-ui-check", "my-ui-menu"
// No prefix (use icon names directly)
addCollection(uiIcons, false);
// Icons available as: "close", "check", "menu"
// Explicitly use collection prefix
addCollection(uiIcons, true);
// Same as default: "ui:close", "ui:check", "ui:menu"Best practices for setting up icons in offline mode.
import { addIcon, addCollection } from "@iconify/react/offline";
// Strategy 1: Individual icons for specific use cases
function setupCriticalIcons() {
const criticalIcons = {
logo: {
body: '<path d="...company logo path..."/>',
width: 120,
height: 40
},
loading: {
body: '<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/>',
width: 24,
height: 24
}
};
Object.entries(criticalIcons).forEach(([name, data]) => {
addIcon(name, data);
});
}
// Strategy 2: Icon collections by feature
function setupFeatureIcons() {
// Navigation icons
addCollection({
prefix: "nav",
icons: {
home: { body: '<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>' },
search: { body: '<path d="M15.5 14h-.79l-.28-.27A6.5 6.5 0 1 0 13 14.41l.27.28v.79l5 4.99L19.49 19l-4.99-5zm-6 0A4.5 4.5 0 1 1 14 9.5 4.5 4.5 0 0 1 9.5 14z"/>' },
settings: { body: '<path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"/>' }
},
width: 24,
height: 24
});
// Form icons
addCollection({
prefix: "form",
icons: {
email: { body: '<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/>' },
password: { body: '<path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM12 17c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM15.1 8H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>' },
submit: { body: '<path d="M2,21L23,12L2,3V10L17,12L2,14V21Z" />' }
},
width: 24,
height: 24
});
}
// Strategy 3: Load from bundled icon data
async function loadIconsFromBundle() {
// Import pre-compiled icon data
const iconBundle = await import('./assets/icon-bundle.json');
// Add all collections from bundle
iconBundle.collections.forEach(collection => {
addCollection(collection);
});
// Add individual icons from bundle
Object.entries(iconBundle.individual || {}).forEach(([name, data]) => {
addIcon(name, data);
});
}
// Initialize icons on app start
export async function initializeOfflineIcons() {
setupCriticalIcons();
setupFeatureIcons();
await loadIconsFromBundle();
console.log("Offline icons initialized");
}Handle cases where icons are not found in offline storage.
import { Icon } from "@iconify/react/offline";
// Component with fallback for missing icons
function SafeIcon({ icon, fallback = "❓", ...props }) {
return (
<Icon
icon={icon}
fallback={fallback}
{...props}
/>
);
}
// Usage
<SafeIcon icon="might-not-exist" fallback={<span>⭐</span>} />
// With children as fallback
<Icon icon="missing-icon">
<span className="icon-placeholder">?</span>
</Icon>
// Conditional rendering based on icon availability
function ConditionalIcon({ iconName, children }) {
// Note: In offline mode, you'd need to track what icons are available
// This is a conceptual example
return (
<Icon icon={iconName}>
{children}
</Icon>
);
}Offline-specific performance considerations and optimizations.
import { Icon, InlineIcon, addCollection } from "@iconify/react/offline";
import { memo } from 'react';
// Pre-memoized components are already optimized, but you can add additional memoization
const OptimizedIcon = memo(Icon);
const OptimizedInlineIcon = memo(InlineIcon);
// Batch icon additions during app initialization
function initializeIcons() {
// Group related icons for better organization
const iconGroups = [
{ name: 'ui', data: uiIconCollection },
{ name: 'brands', data: brandIconCollection },
{ name: 'arrows', data: arrowIconCollection }
];
// Add all collections at once
iconGroups.forEach(({ name, data }) => {
console.log(`Loading ${name} icons...`);
addCollection(data);
});
console.log('All offline icons loaded');
}
// Use with React.lazy for code splitting
const IconWrapper = memo(({ icon, ...props }) => {
return <Icon icon={icon} {...props} />;
});
export { OptimizedIcon, OptimizedInlineIcon, IconWrapper };