iconly
v4.2.0
Published
Iconly is designed to load and cache SVG icons in the browser, using IndexedDB to store the data. It retrieves the icons from a given SVG file, stores them in IndexedDB, and inserts them into the DOM for easy access and use.
Maintainers
Readme
iconly
A lightweight utility for SVG icon sprites in the browser. Load and cache an external sprite file (iconly), or build one from your own icon objects with tree-shaking (iconly/sprite).
Features
- Factory-based API with
createIconly()— fetch and cache an external sprite file. - IndexedDB, memory, or session storage strategies.
iconly/sprite— build a sprite from icon objects; no fetch, no storage, zero extra runtime deps.init()andrender()return aResultand never throw.
Installation
npm install iconlyQuick Start: external sprite file
import { createIconly } from 'iconly';
const iconLoader = createIconly({
file: './sprite.svg',
version: '1.0',
debug: true,
storage: 'indexeddb',
});
const result = await iconLoader.init();
if (!result.ok) {
console.error(result.error);
}After init(), the SVG sprite is injected into the container inside <div data-iconly="iconset" aria-hidden="true">...</div>.
<svg>
<use href="#icon-name"></use>
</svg>Sprite file format:
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" fill="none">
<symbol id="icon-name" viewBox="0 0 300 300">
<path />
</symbol>
</svg>Quick Start: icon objects
Import icons as ESM modules — your bundler tree-shakes unused ones. iconly only assembles the sprite string and injects it into the DOM.
import { createSprite } from 'iconly/sprite';
import { search, user, trash } from './icons';
const sprite = createSprite({
icons: [search, user, trash],
container: '#app', // string | HTMLElement, defaults to document.body
});
const result = sprite.render();
if (!result.ok) {
console.error(result.error);
}Icon object format (bring your own):
export const search = {
name: 'search', // id for <use href="#search">
viewBox: '0 0 24 24',
body: '<path d="..."/>',
};For SSR or tests — build the string without touching the DOM:
import { buildSpriteString } from 'iconly/sprite';
const svg = buildSpriteString([search, user, trash]);API
iconly
createIconly(config?)— creates an icon loader instance.iconLoader.init()— fetches (or loads from cache) the sprite and injects it into the DOM; returnsResult<void>.iconLoader.abort()— cancels an in-flight fetch.
iconly/sprite
createSprite(config)— creates a sprite builder instance.sprite.render()— builds the sprite fromiconsand injects it into the DOM; returnsResult<void>synchronously.buildSpriteString(icons)— returns the SVG sprite string without DOM access.
Options
createIconly
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| file | string | './icons.svg' | URL of the SVG file containing the icons. |
| version | string | '1.0' | Version of the icon set. |
| debug | boolean | false | Enables debug callbacks and logger debug output. |
| container | string \| HTMLElement | document.body | Container where icons are injected. |
| storage | 'indexeddb' \| 'memory' \| 'session' | 'indexeddb' | Storage strategy for caching icon data. |
| dbName | string | 'iconlyDB' | IndexedDB database name (for indexeddb). |
| storeName | string | 'icons' | IndexedDB store name (for indexeddb). |
| sessionKeyPrefix | string | 'iconly' | SessionStorage key prefix (for session). |
| sanitize | (svg: string) => string | undefined | Optional hook to sanitize SVG before parsing. Runs before built-in hardening. |
| logger | { debug?, error? } | undefined | Optional logger for debug/error output. |
| onError | (error) => void | undefined | Callback invoked on errors. |
| onDebug | (...args) => void | undefined | Callback invoked for debug messages. |
createSprite
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| icons | IconlyIcon[] | — | Icon objects to include in the sprite. |
| container | string \| HTMLElement | document.body | Container where the sprite is injected. |
| sanitize | (svg: string) => string | undefined | Optional hook to sanitize SVG before parsing. Runs before built-in hardening. |
Security
iconly injects SVG into the live DOM. Treat sprite files and icon objects as trusted content.
- Do not pass
fileURLs oricon.bodyvalues from untrusted user input without sanitization. createIconlyandcreateSpriteapply built-in hardening before insertion: event-handler attributes (on*),<script>,<foreignObject>,javascript:/data:text/htmllinks, and SMIL animation elements targetinghrefare stripped.- Built-in hardening is defense in depth, not a full HTML sanitizer. It does not cover, for example,
<style>CSS vectors or external references in<use>/<image>. For untrusted SVG, pass asanitizehook and use a dedicated library such as DOMPurify:
import DOMPurify from 'dompurify';
const iconLoader = createIconly({
file: userProvidedUrl, // only after your own URL allowlisting
sanitize: (svg) =>
DOMPurify.sanitize(svg, { USE_PROFILES: { svg: true, svgFilters: true } }),
});buildSpriteString returns raw SVG and does not touch the DOM. When using it directly (SSR, tests), sanitize the output yourself if the source icons are not fully trusted.
In iconly/sprite, name and viewBox are escaped in attributes; body is inserted as-is and sanitized only when rendered via createSprite().render() or when you sanitize the string yourself.
Error handling
init()andrender()never throw; they return aResultwithok: falseanderrordetails.- When
debugisfalse, debug messages are suppressed. - Errors still trigger
onErrorandlogger.error(if provided), even whendebugisfalse. - Call
iconLoader.abort()to cancel a fetch (fetch_abortederror code).
License
MIT
