pro-laico

icons

by pro-laico
atomic-payload
Custom fields
v3
>=3.0.0
MIT

Overview

Summary generated from the README

Adds Icon and IconSet collections to Payload, with SVGs optimized on upload through a formatSVG hook. It provides an admin icon select, an Icon server component that resolves icons by name from the active set, and blocks for picking or pasting SVGs. Part of the Atomic Payload suite and depends on its core and atomic packages; svgo and svg-path-bbox are optional peers for SVG uploads.

Features

  • Icon upload collection with SVG optimization on upload
  • IconSet collection for grouping icons
  • Admin select widget and row label for choosing icons
  • Icon server component that resolves icons by name
  • Build-time scanner and admin panel comparing requested icon names with the set
  • Optional runtime tracking of icon names that fail to resolve

Use cases

  • Manage a site icon library in the CMS instead of hardcoding SVG files
  • Catch missing or misspelled icon names before and after deployment
  • Let editors pick or paste SVGs inside content blocks

From the author

Atomic Payload icons package. Provides Icon and IconSet Payload collections, an SVG-optimizing formatSVG hook, SVG extraction helpers, and the AtomicIcon component.

Installation

npm i @pro-laico/icons

37

Stars

0

Forks

0

Open Issues

2 months ago

Last Updated

2

Weekly Downloads

v0.5.0

npm Version

286.3 KB

Unpacked Size

4

Dependencies

Repository stars

Trends appear after 7 days of data. Collecting since Oct 22 — 2 daily snapshots so far.

Shared by 10 plugins in pro-laico/atomic-payload.

npm weekly downloads

Trends appear after 7 days of data. Collecting since Oct 22 — 2 daily snapshots so far.

Each point is npm's rolling 7-day download count.

Health Score

56/100Good

Composite score based on GitHub activity, stars, npm downloads, publish recency, dependency count, and package size.

Badge for your README

Payload Directory health badge
Markdown
[![Payload Directory](https://payloaddirectory.dev/badge/1128550352-icons.svg)](https://payloaddirectory.dev/plugins/1128550352-icons)
HTML
<a href="https://payloaddirectory.dev/plugins/1128550352-icons"><img src="https://payloaddirectory.dev/badge/1128550352-icons.svg" alt="Payload Directory"></a>
Updated Jul 28, 2026Created Jan 5, 2026Published Jun 27, 2026

README

Atomic Payload Icons Plugin

Turns SVG icons into first-class CMS content — an upload collection optimized on upload, an IconSet grouping collection, an admin select widget, an <Icon> server component, and child blocks for picking or pasting SVGs. Part of Atomic Payload.

Atomic Payload dependencies

  • @pro-laico/core — cache revalidation hooks plus the cached iconSet / icon getters that resolve icons by name.
  • @pro-laico/atomic — the IconChild / SVGChild block components render via its children subpath.

svgo and svg-path-bbox are optional peers — only needed if you upload SVGs through the formatSVG hook.

Exports

ImportWhat's there
.Plugin barrel — iconsPlugin plus the extractSvgContent / extractSvgProps SVG helpers and the IconLabelPath / IconUsagePanelPath import-map constants.
./schemaPayload Icon / IconSet type-augmentation stubs.
./Icon<Icon name="..." /> server component (resolves from the active IconSet).
./AtomicIconAtomicIcon marker glyph for atomic block types — client-safe entry kept off the server-only main barrel.
./admin/iconRowLabelAdmin row label (loaded via import map).
./admin/iconSelectcreateIconSelect factory for the admin select widget.
./blocks/iconChildIconChild block config (exported Icon const + createIconBlock factory).
./blocks/iconChild/componentIconChild block renderer.
./blocks/svgChildSVGChild block config (exported SVGBlock const + createSvgBlock factory).
./blocks/svgChild/componentSVGChild block renderer.
./admin/iconUsagePanelServer UIField for the IconSet edit view — diffs the build-time usage manifest against the set's icons.
./scanBuild-time usage scanner — scanIconUsages, writeIconUsageManifest, loadIconUsageManifest, and the pure extractIconUsages.

Requested-icons usage manifest

When you reference icons by name in your app (<Icon name="chevron" />), the IconSet collection has no idea which names your code actually needs — names live in the CMS, and a typo just falls back at render time. The usage manifest closes that loop: a build-time scan collects every literal name you request and an opt-in admin panel diffs it against the icons defined in the set, flagging the missing ones with their file:line.

1. Scan your source

Run the CLI (e.g. as a prebuild script or CI step). Only string literals are collected — name="x", name='x', name={"x"}, and non-interpolated name={`x`}. Dynamic name={expr} is intentionally skipped.

# scan ./src and ./app, write icon-usage-manifest.json
npx atomic-icons-scan

# explicit roots / output / component names / extensions
atomic-icons-scan src app --out icon-usage-manifest.json --component Icon --ext tsx,jsx

Or call it programmatically:

import { scanIconUsages, writeIconUsageManifest, resolveManifestPath } from '@pro-laico/icons/scan'

const { manifest } = scanIconUsages({ roots: ['src', 'app'] })
writeIconUsageManifest(manifest, resolveManifestPath())

2. Show the panel in the admin

Opt in via iconSetOptions.usagePanel. The panel reads the manifest server-side and diffs it live against the icons you're editing:

iconsPlugin({
  iconSetOptions: {
    usagePanel: true,
    // optional — defaults to $ICON_USAGE_MANIFEST, then icon-usage-manifest.json at cwd
    usageManifestPath: 'icon-usage-manifest.json',
  },
})

The manifest path resolves from the usageManifestPath option → the ICON_USAGE_MANIFEST env var → icon-usage-manifest.json in the server's working directory. When no manifest exists yet, the panel renders a hint telling editors to run the scan.

Names are matched exactly against each icon's kebab-cased name, mirroring how <Icon> resolves at runtime. Because the scan never executes your code, an <Icon name="…"> written inside a string or comment may also be picked up — a harmless over-count for an inventory, where missing a real usage would be the worse failure.

3. Track runtime misses (live)

The static scan only sees string literals. To also catch what production actually requests — including dynamic <Icon name={slug} /> and genuine misses — enable trackRequests:

iconsPlugin({
  iconSetOptions: { usagePanel: true },
  trackRequests: true,
})

This registers an iconRequest collection and makes <Icon> record every name that fails to resolve against the active set — throttled (at most once per name per minute per process), deferred via Next's after() so it never blocks the response, and best-effort (failures are swallowed). Misses surface in the usage panel's "Missing from this set" list with a live ×count and last-seen date, and dynamic names absent from the code scan are flagged as such. Force-disable the recorder with ICON_USAGE_TRACKING=false.

The panel becomes a three-way compare: names requested in code (manifest) vs requested in production (iconRequest) vs defined in the set you're editing — so missing, dynamic-only, and (via the present list) unused names are all visible. Counts reflect server renders, not unique visitors (static/ISR pages render once per revalidation).

Similar plugins