daun/statamic-icon-button-fieldtypes
Adds Icon and Button fieldtypes to Statamic's control panel, letting editors pick icons and configure button labels, links, and styles without touching templates. A small, focused addon that keeps content flexible and design-consistent.
This addon gives Statamic (Laravel) sites a proper icon fieldtype: you pick an icon in the Control Panel instead of typing a class name or hand-writing SVG, and the value is stored on the entry so templates can render it.
Install and publish
composer require <vendor>/<package>
php artisan vendor:publish --tag=<package>-config # publishes the icon config
Look at the config file first. Everything you can pick in the CP is defined there — which icon sets are available, their source (local SVG directory, a bundled set, or a CDN-backed library), and the labels shown to editors. Read this before touching a fieldset; most "the picker is empty" reports are a config issue, not a bug.
Add the field to a fieldset (resources/fieldsets/… or inline in a collection's YAML):
icon:
type: icon
display: Icon
icon_set: default
Render it in Antlers or Blade. The stored value is the icon's identifier, so resolve it through the package's render path rather than echoing it:
{{ if icon }}
<span class="icon">{{ svg :src="icon" }}</span>
{{ /if }}
First real use case: a "service card" set inside a page builder — one icon field per card, editors pick from your brand-approved set, and the partial does the markup. That exercises the whole loop (config → fieldset → content → template) in about ten minutes.
Config as the source of truth, fieldsets as the surface. Define sets once in config, then reference them from many fieldsets. Keep a small "default" set for general marketing pages and a narrower set for anything where a wrong icon is a brand problem, so editors can't wander into a 900-icon library for a checkout button.
Wrap rendering in one partial. One partials/icon.antlers.html (or a Blade component) that takes the handle, applies size/class, and handles the empty case. When the icon library changes, you fix one file:
{{# partials/icon.antlers.html #}}
{{ if icon }}
<span class="icon icon--{{ size ?? 'md' }}" aria-hidden="true">{{ svg :src="icon" }}</span>
{{ /if }}
Reuse it from Bard sets, Grid fields, and plain entry templates alike.
Validate on save. Icon handles are free-form strings once stored, so add a validation rule (or a saving listener) that rejects unknown handles. That catches the case where an editor's content survives a config change that removed the set.
Bard / Replicator integration. Add the icon field to a set and it behaves like any other field — the value travels with the set's data, so {{ sets }}{{ icon }}{{ /sets }} loops work without extra handling.
Programmatic writes (imports, seeding, API endpoints). Set the field to the icon handle string, exactly as the picker would. Seed content with handles that exist in your config, and run the site's cache clear afterwards — Statamic's content cache and the CP's asset manifest are the two things that go stale.
Multi-site / multi-brand. Publish one config per environment is usually the wrong instinct; instead define distinct named sets in one config and select the appropriate set on the fieldset per site. It keeps a single deployable artifact.
1.1.0 changes the config key naming — this is the upgrade landmine. The package now reads unprefixed icon config keys, which Statamic only permits from the CMS version referenced in the release notes. If you have a previously published config file using the old prefixed keys, the new version will not read them: the keys are silently ignored, and you get empty pickers or a fallback set rather than an error. After composer update, diff your published config against the package's and rename the keys, or delete and re-publish. Then php please cache:clear and php artisan config:clear.
2. Pin the CMS version. The native icon picker field is a fairly recent Statamic feature. On an older CMS the field won't render properly, and Composer's constraint on the addon may not be tight enough to stop you. Check the addon's statamic/cms requirement before upgrading, and bump the CMS in the same deploy.
3. Config caches bite in production. php artisan config:cache freezes the icon config. Any deploy that changes available sets must re-run it, or the CP keeps serving the old library while your templates assume new handles.
4. Don't echo raw handles into markup paths. Stored values are strings from the CP, but they can also arrive from imports and API writes. Resolve them through the package/SVG tag so a bad or malicious value can't inject markup. Only enable icon sets you trust — a remote/CDN-backed set is a supply-chain surface.
5. Renaming handles breaks content. Treat icon handles as content keys: rename in config and you orphan every entry using the old one. Keep the old handle as an alias, or write a one-off migration that rewrites the field across entries before removing it.
6. Debugging an empty picker. In order: is the config published and cached-cleared? Do the set keys match what the fieldset requests via icon_set? Is the SVG source directory readable by the web user? Are the CMS and addon versions compatible with the native picker? That sequence resolves nearly every report.
7. Extension points worth knowing. Because the picker and rendering are config-driven, swapping the icon source (local directory ↔ bundled library) is a config edit, not a code change — but any template that hard-coded a specific set's naming convention will need review. Keep the rendering partial as the only place that knows about the library, and future swaps stay cheap.
8. Testing. Assert that saved fixture content's icon handles all exist in the current config — a cheap test that catches both the config-rename trap and accidental handle renames before they reach production.
How can I help you explore Laravel packages today?