Icon Field
A field in Payload CMS that lets editors choose a Lucide icon from a dropdown with a live preview.

Install
pnpm dlx [email protected] add https://p.livog.com/r/icon-field.json
Code
import type { SelectField } from 'payload'
import iconNodes from 'lucide-static/icon-nodes.json'
export type IconOption = {
value: string
label: string
}
export type IconField = (overrides?: Partial<SelectField>) => SelectField
const iconField: IconField = (overrides = {}) => {
const baseField = {
name: 'icon',
...overrides,
type: 'select',
interfaceName: 'LucideIcon',
required: false,
hasMany: false,
options: Object.keys(iconNodes).map((slug) => {
const label = slug
.split('-')
.map((segment) => {
if (/^\d+$/.test(segment)) return segment
return segment
.replace(/^[a-z]/, (c) => c.toUpperCase())
.replace(/(\d)([a-z])/g, (_, d, l) => d + l.toUpperCase())
})
.join(' ')
return {
value: slug,
label
}
}),
admin: {
...overrides.admin,
components: {
...overrides.admin?.components,
Field: {
path: '@/payload/fields/icon/component#IconComponent'
}
}
}
} as SelectField
return baseField
}
export { iconField }
Usage
Add an icon picker to any collection or global:
import { iconField } from '@/payload/fields/icon'
export const Category: CollectionConfig = {
slug: 'categories',
fields: [
{ name: 'title', type: 'text', required: true },
iconField(), // adds an “icon” select powered by Lucide
],
}
Example
import { Container } from '@/components/container'
import { DynamicIcon } from 'lucide-react/dynamic';
import { Section } from '@/components/section'
export default function IconFieldDemo() {
return (
<Section spacing="xxsmall">
<Container>
<div className="grid grid-cols-5 items-center justify-items-center gap-4 p-8">
<DynamicIcon name="home" className="size-10" />
<DynamicIcon name="settings" className="size-10" />
<DynamicIcon name="user" className="size-10" />
<DynamicIcon name="arrow-down-0-1" className="size-10" />
<DynamicIcon name="axis-3d" className="size-10" />
</div>
</Container>
</Section>
)
}
The icon field stores the values specified in name.