0
# Offline Usage
1
2
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.
3
4
## Package Import
5
6
```typescript
7
// Import from offline sub-package
8
import { Icon, InlineIcon, addIcon, addCollection } from "@iconify/react/offline";
9
```
10
11
## Capabilities
12
13
### Offline Icon Component
14
15
Block-level icon component optimized for offline usage with memoization for better performance.
16
17
```typescript { .api }
18
/**
19
* Offline block icon component with middle vertical alignment
20
* Memoized for optimal performance with pre-loaded icons
21
* @param props - Icon properties including icon data/name and customizations
22
* @param ref - Forward ref to the rendered SVG or span element
23
*/
24
const Icon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<IconElement>>;
25
```
26
27
**Usage Examples:**
28
29
```typescript
30
import { Icon, addIcon } from "@iconify/react/offline";
31
32
// Add icon first
33
const starIcon = {
34
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"/>',
35
width: 24,
36
height: 24
37
};
38
39
addIcon("star", starIcon);
40
41
// Use icon by name
42
<Icon icon="star" />
43
44
// Use icon data directly
45
<Icon icon={starIcon} />
46
47
// With customizations (same as online version)
48
<Icon
49
icon="star"
50
width="32"
51
height="32"
52
color="gold"
53
rotate={1}
54
/>
55
```
56
57
### Offline InlineIcon Component
58
59
Inline icon component optimized for offline usage with memoization.
60
61
```typescript { .api }
62
/**
63
* Offline inline icon component with baseline vertical alignment
64
* Memoized for optimal performance with pre-loaded icons
65
* @param props - Icon properties including icon data/name and customizations
66
* @param ref - Forward ref to the rendered SVG or span element
67
*/
68
const InlineIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<IconElement>>;
69
```
70
71
**Usage Examples:**
72
73
```typescript
74
import { InlineIcon, addIcon } from "@iconify/react/offline";
75
76
// Add icons first
77
addIcon("heart", heartIconData);
78
addIcon("star", starIconData);
79
80
// Use in text
81
<p>
82
Rate this: <InlineIcon icon="star" color="gold" />
83
<InlineIcon icon="heart" color="red" />
84
</p>
85
86
// In buttons
87
<button>
88
<InlineIcon icon="star" /> Add to Favorites
89
</button>
90
```
91
92
### Add Single Icon (Offline)
93
94
Add a single icon to offline storage for use by name.
95
96
```typescript { .api }
97
/**
98
* Add single icon to offline storage
99
* @param name - Icon name to use when referencing the icon
100
* @param data - Icon data containing SVG and metadata
101
*/
102
function addIcon(name: string, data: IconifyIcon): void;
103
```
104
105
**Usage Examples:**
106
107
```typescript
108
import { addIcon } from "@iconify/react/offline";
109
110
// Add custom icon
111
const customIcon = {
112
body: '<circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/>',
113
width: 24,
114
height: 24
115
};
116
117
addIcon("smiley", customIcon);
118
119
// Add with namespace
120
addIcon("ui:close", {
121
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"/>',
122
width: 24,
123
height: 24
124
});
125
126
// Now use: <Icon icon="smiley" /> or <Icon icon="ui:close" />
127
```
128
129
### Add Icon Collection (Offline)
130
131
Add multiple icons from a collection to offline storage with flexible prefix handling.
132
133
```typescript { .api }
134
/**
135
* Add icon collection to offline storage
136
* @param data - Icon collection data with prefix and icons
137
* @param prefix - Optional custom prefix (string) or use collection prefix (true/undefined) or no prefix (false)
138
*/
139
function addCollection(data: IconifyJSON, prefix?: string | boolean): void;
140
```
141
142
**Usage Examples:**
143
144
```typescript
145
import { addCollection } from "@iconify/react/offline";
146
147
// Add collection with its own prefix
148
const uiIcons = {
149
prefix: "ui",
150
icons: {
151
close: {
152
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"/>',
153
},
154
check: {
155
body: '<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>',
156
},
157
menu: {
158
body: '<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>',
159
}
160
},
161
width: 24,
162
height: 24
163
};
164
165
// Use collection prefix (default behavior)
166
addCollection(uiIcons);
167
// Icons available as: "ui:close", "ui:check", "ui:menu"
168
169
// Use custom prefix
170
addCollection(uiIcons, "my-ui-");
171
// Icons available as: "my-ui-close", "my-ui-check", "my-ui-menu"
172
173
// No prefix (use icon names directly)
174
addCollection(uiIcons, false);
175
// Icons available as: "close", "check", "menu"
176
177
// Explicitly use collection prefix
178
addCollection(uiIcons, true);
179
// Same as default: "ui:close", "ui:check", "ui:menu"
180
```
181
182
### Pre-loading Icon Strategy
183
184
Best practices for setting up icons in offline mode.
185
186
```typescript
187
import { addIcon, addCollection } from "@iconify/react/offline";
188
189
// Strategy 1: Individual icons for specific use cases
190
function setupCriticalIcons() {
191
const criticalIcons = {
192
logo: {
193
body: '<path d="...company logo path..."/>',
194
width: 120,
195
height: 40
196
},
197
loading: {
198
body: '<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/>',
199
width: 24,
200
height: 24
201
}
202
};
203
204
Object.entries(criticalIcons).forEach(([name, data]) => {
205
addIcon(name, data);
206
});
207
}
208
209
// Strategy 2: Icon collections by feature
210
function setupFeatureIcons() {
211
// Navigation icons
212
addCollection({
213
prefix: "nav",
214
icons: {
215
home: { body: '<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>' },
216
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"/>' },
217
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"/>' }
218
},
219
width: 24,
220
height: 24
221
});
222
223
// Form icons
224
addCollection({
225
prefix: "form",
226
icons: {
227
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"/>' },
228
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"/>' },
229
submit: { body: '<path d="M2,21L23,12L2,3V10L17,12L2,14V21Z" />' }
230
},
231
width: 24,
232
height: 24
233
});
234
}
235
236
// Strategy 3: Load from bundled icon data
237
async function loadIconsFromBundle() {
238
// Import pre-compiled icon data
239
const iconBundle = await import('./assets/icon-bundle.json');
240
241
// Add all collections from bundle
242
iconBundle.collections.forEach(collection => {
243
addCollection(collection);
244
});
245
246
// Add individual icons from bundle
247
Object.entries(iconBundle.individual || {}).forEach(([name, data]) => {
248
addIcon(name, data);
249
});
250
}
251
252
// Initialize icons on app start
253
export async function initializeOfflineIcons() {
254
setupCriticalIcons();
255
setupFeatureIcons();
256
await loadIconsFromBundle();
257
258
console.log("Offline icons initialized");
259
}
260
```
261
262
### Missing Icon Handling
263
264
Handle cases where icons are not found in offline storage.
265
266
```typescript
267
import { Icon } from "@iconify/react/offline";
268
269
// Component with fallback for missing icons
270
function SafeIcon({ icon, fallback = "❓", ...props }) {
271
return (
272
<Icon
273
icon={icon}
274
fallback={fallback}
275
{...props}
276
/>
277
);
278
}
279
280
// Usage
281
<SafeIcon icon="might-not-exist" fallback={<span>⭐</span>} />
282
283
// With children as fallback
284
<Icon icon="missing-icon">
285
<span className="icon-placeholder">?</span>
286
</Icon>
287
288
// Conditional rendering based on icon availability
289
function ConditionalIcon({ iconName, children }) {
290
// Note: In offline mode, you'd need to track what icons are available
291
// This is a conceptual example
292
return (
293
<Icon icon={iconName}>
294
{children}
295
</Icon>
296
);
297
}
298
```
299
300
### Performance Optimization
301
302
Offline-specific performance considerations and optimizations.
303
304
```typescript
305
import { Icon, InlineIcon, addCollection } from "@iconify/react/offline";
306
import { memo } from 'react';
307
308
// Pre-memoized components are already optimized, but you can add additional memoization
309
const OptimizedIcon = memo(Icon);
310
const OptimizedInlineIcon = memo(InlineIcon);
311
312
// Batch icon additions during app initialization
313
function initializeIcons() {
314
// Group related icons for better organization
315
const iconGroups = [
316
{ name: 'ui', data: uiIconCollection },
317
{ name: 'brands', data: brandIconCollection },
318
{ name: 'arrows', data: arrowIconCollection }
319
];
320
321
// Add all collections at once
322
iconGroups.forEach(({ name, data }) => {
323
console.log(`Loading ${name} icons...`);
324
addCollection(data);
325
});
326
327
console.log('All offline icons loaded');
328
}
329
330
// Use with React.lazy for code splitting
331
const IconWrapper = memo(({ icon, ...props }) => {
332
return <Icon icon={icon} {...props} />;
333
});
334
335
export { OptimizedIcon, OptimizedInlineIcon, IconWrapper };
336
```