Payload Plugins
Pluginspayload-icons

Reference

Plugin options, environment variables, the CLI scan command, and every export payload-icons ships.

For AI / LLMs: View Markdown

Plugin options

iconsPlugin(options?) is the single entry point. One call registers the icon collection (upload pipeline, on-save optimizer), the iconSet grouping collection, and the iconRequest diagnostics collection. It's zero-config: everything is on by default.

Every collection the plugin registers is one key under collections, and each key is the uniform { slug?, overrides?, options? } shape: slug renames it, overrides is a Partial<CollectionConfig> Payload passthrough, and options is this plugin's own knobs for that collection. A collection the plugin can work without also takes false to skip it.

How an override merges

collections.<name>.overrides is a Partial<CollectionConfig>what Payload has, you can override. There's no allowlist of permitted keys (slug is its own key alongside overrides, not inside it):

KeyMerge
slug (own key)Renamed. The plugin threads the new slug everywhere it's referenced — the set's upload field, the marker, the clear-requests endpoint.
overrides.fieldsAppended after the plugin's. A duplicate name is a boot error naming the plugin, collection, and field, not a bare DuplicateFieldName.
overrides.hooksMerged per phase — yours run after the plugin's, so a beforeChange on icon sees the already-optimized SVG.
overrides.access / admin / upload / customShallow-merged, so you replace one key without losing the rest (admin: { group: 'Branding' } keeps useAsTitle).
overrides.defaultPopulate / forceSelectMerged as selects.
everything else in overridesReplaced — labels, versions, defaultSort, timestamps, endpoints, …

Pass options to customize. The Reference tab is the interactive view; TypeScript is the same shape in code, every defaulted option written out.

enabledbooleandefault true

When false, the plugin is a no-op; no collections are registered.

collections{ icon?, iconSet?, iconRequest? }default {}

The collections the plugin registers, one key each.

iconCollectionOptiondefault {}

The icon upload collection — always registered, so no false and no plugin options.

slugstringdefault 'icon'

Rename it; the icon set's upload field and the plugin marker re-point automatically.

overridesPartial<CollectionConfig>

Payload config merged onto the plugin's by the shared merge rules. Rename with the sibling slug key, not here.

iconSetfalse | CollectionOption<IconSetOptions>default {}

false skips the iconSet collection entirely (only icon is registered) — use it when you want icons in the CMS but not the grouping/active-set concept.

slugstringdefault 'iconSet'

Rename it; the plugin follows it.

overridesPartial<CollectionConfig>

Payload config merged onto the plugin's by the shared merge rules — re-group it, wire live preview through admin.preview / admin.livePreview, turn versions off, add fields. Rename with the sibling slug key, not here.

optionsIconSetOptions

This collection's own knobs.

usagePanelbooleandefault true

The IconSet "Requested icons" panel: shows which icons your code needs vs what a set provides (scanned live in dev, from the manifest in prod, plus runtime misses). Set false to omit it.

iconRowFieldsField[]default []

Extra fields appended to every row of the icon set's iconsArray, after the built-in name and icon upload — an alias list, a per-icon note. An iconSet.overrides.fields override can't reach inside the array, which is why this is its own option under the iconSet's options.

iconRequestfalse | CollectionOptiondefault {}

false skips the iconRequest diagnostics collection and its clear endpoint — nothing tracks missing icons. Otherwise <Icon> records every name that fails to resolve at runtime (throttled, fire-and-forget), including dynamic names a static scan can't see, surfaced in the usage panel. No plugin options. To force-off only the recorder at runtime, leave the collection registered and set ICON_USAGE_TRACKING=false.

slugstringdefault 'iconRequest'

Rename it; the clear endpoint follows it.

overridesPartial<CollectionConfig>

Payload config merged onto the plugin's by the shared merge rules. Rename with the sibling slug key, not here.

optionsIconsOptionsdefault {}

The plugin's own knobs.

accessIconsAccessOptions

Per-endpoint gates for the plugin's HTTP endpoints — one EndpointAccess ((req) => boolean | Promise<boolean>) per endpoint. See Gating endpoints.

clearRequestsEndpointAccessdefault any logged-in user

Gates DELETE /payload-icons/icon-requests (the usage panel's Clear button). Only registered while the iconRequest collection is on.

import { iconsPlugin } from '@pro-laico/payload-icons'

// Defaulted options written out. This is what `iconsPlugin()` does with no args.
iconsPlugin({
  enabled: true,
  // one key per registered collection, each `{ slug?, overrides?, options? }`; `false` skips a collection
  collections: {
    // the icon upload collection — always registered, so no `false`, and no plugin `options`:
    icon: {
      // slug: 'glyph', // renamed everywhere the plugin refers to it
      overrides: {
        // labels: { singular: 'Glyph', plural: 'Glyphs' }, // replaced
        // admin: { group: 'Branding' },                    // shallow-merged onto the plugin's admin
        // access: { read: () => true },                    // shallow-merged onto the plugin's access
        // fields: [{ name: 'note', type: 'text' }],        // appended after the built-ins
        // hooks: { beforeChange: [mine] },                 // merged per phase; yours run last
      },
    },
    // the iconSet collection; `false` omits it:
    iconSet: {
      overrides: {
        // versions: false,                                 // drafts are on by default
        // fields: [{ name: 'description', type: 'textarea' }],
        // admin: { livePreview: { url: ({ data }) => `${process.env.SITE_URL}/preview/${data.id}` } },
      },
      options: {
        usagePanel: true, // the "Requested icons" panel; set false to omit
        iconRowFields: [], // e.g. [{ name: 'aliases', type: 'text', hasMany: true }]
      },
    },
    // the iconRequest diagnostics collection; `false` omits it (no runtime miss tracking):
    iconRequest: {},
  },
  options: {
    access: {
      // clearRequests: ({ user }) => Boolean(user), // default: any logged-in user
    },
  },
})

Environment variables

Two env vars tune usage detection at runtime, independent of the plugin options.

Prop

Type

CLI commands

CommandWhat
payload-icons-scanScan source for <Icon name> and write the usage manifest (icon-usage-manifest.json). Run it in your production build so the Requested icons panel works where source isn't on disk. Scans ./src and ./app; -o sets the manifest path, --component Glyph scans a different component. See Collections.

Endpoints

Method & pathWhat
DELETE /api/payload-icons/icon-requestsClears every iconRequest doc — the action behind the usage panel's Clear button. Gated by options.access.clearRequests (any logged-in user by default; see Gating endpoints). The gate is the outer door only — the delete runs as the caller (overrideAccess: false), so the iconRequest collection's own delete access still applies and a caller the gate admits can still clear nothing. Registered only while the iconRequest collection is on; the path is fixed (a renamed iconRequest slug changes the delete target, not the route).

Icon-set activation itself happens in the admin, or through the companion @pro-laico/payload-dev-tools /dev panel.

Exports

ExportFromWhat
iconsPlugin@pro-laico/payload-iconsThe plugin factory and single entry point (also the default export).
IconsPluginOptions@pro-laico/payload-iconsThe iconsPlugin(options?) argument type: { enabled?, collections?, options? }.
IconsCollectionsOptions@pro-laico/payload-iconsThe collections shape: { icon?, iconSet?, iconRequest? }.
IconSetOptions@pro-laico/payload-iconsThe iconSet collection's own knobs: { usagePanel?, iconRowFields? }.
IconsOptions@pro-laico/payload-iconsThe root options shape: { access? }.
IconsAccessOptions@pro-laico/payload-iconsThe options.access gate-map shape: { clearRequests? }.
EndpointAccess@pro-laico/payload-iconsThe endpoint-gate function type (req) => boolean | Promise<boolean>; see Gating endpoints.
IconDoc@pro-laico/payload-iconsThe icon document type: { id, filename?, svgString?, optimized? }.
readIconsMarker@pro-laico/payload-iconsThe typed view of config.custom.payloadIcons: { options, iconSlug, iconSetSlug, iconRequestSlug }. The supported way to discover the slugs the plugin registered — they follow collections.<name>.slug, and iconSetSlug / iconRequestSlug are null when that collection is off. Returns undefined when the plugin isn't registered.
PayloadIconsMarker@pro-laico/payload-iconsThe marker's type.
extractSvgContent@pro-laico/payload-iconsPull the inner markup out of an svgString to inline it in your own <svg>.
extractSvgProps@pro-laico/payload-iconsParse an svgString's root attributes (viewBox, etc.) onto your own <svg>.
createIcon@pro-laico/payload-icons/components/IconFactory that takes a Payload handle and returns the <Icon name="…" /> server component — const Icon = createIcon(getPayload({ config })) (resolves through the active set). Props: name, optional fallback and draft, plus any SVG attribute.
getIconSvg@pro-laico/payload-icons/cacheResolve one icon name to its svgString through the active set (server-only; one cached, tagged read serves the whole set).
payload-icons-scanbinCLI that scans source for <Icon name> and writes the usage manifest.

Collections & globals

iconsPlugin() registers the icon, iconSet, and iconRequest collections — see Collections for their fields, hooks, and the icon-use detection panel.

On this page