CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-iconify--react

React component for rendering SVG icons from the Iconify ecosystem with over 200,000 icons from 150+ icon sets.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

offline.mddocs/

Offline Usage

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.

Package Import

// Import from offline sub-package
import { Icon, InlineIcon, addIcon, addCollection } from "@iconify/react/offline";

Capabilities

Offline Icon Component

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} 
/>

Offline InlineIcon Component

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 Single Icon (Offline)

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 Icon Collection (Offline)

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"

Pre-loading Icon Strategy

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");
}

Missing Icon Handling

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>
  );
}

Performance Optimization

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 };

docs

api-loading.md

building.md

components.md

index.md

offline.md

storage.md

tile.json