Skip to content

Font Picker

Font::make('default_font') renders a searchable typography picker compiled to FilamentCraft's FontPickerField — far more than a <select>. It is the control you use for every typography setting in a theme. Uses the instant live() update mode.

php
use FilamentCraft\Settings\Types\Font;

Font::make('default_font')
    ->cssVar('--font-default')
    ->default('inter');
MethodEffect
onlyCategory(array|string $categories)Restrict the picker to one or more categories.
only(array|string $slugs)Restrict the picker to specific catalog slugs (a brand-kit allow-list).
clearable(bool $value = true)Show a "reset to theme default" control (used by per-section typography).
The Bunny Fonts picker
The font picker with per-row live previews.

What the picker does

  • Live catalog from https://fonts.bunny.net/list — fetched once and cached server-side for 24 hours, with system stacks added locally.
  • Popular tab pinned first — Inter, Roboto, Playfair Display, JetBrains Mono, and more, ahead of the alphabetical roster.
  • Per-row preview in the option's own font, lazy-loaded as you scroll.
  • Searchable, with category chips: Popular · All · System · Sans · Serif · Display · Mono · Handwriting.
  • Keyboard navigation: arrow up/down to highlight, Enter to commit, Escape to close.
  • Live preview: pick a font → the setting persists → the iframe <head> re-syncs (Bunny <link> injected, <style id="fc-tokens"> updated).

Restricting categories

php
Font::make('heading_font')
    ->cssVar('--font-heading')
    ->onlyCategory(['display', 'serif'])   // hides sans / mono / handwriting
    ->default('playfair-display');

onlyCategory() accepts a single string or an array. Valid categories mirror the chips: system, sans, serif, display, mono, handwriting.

To restrict a picker to a fixed set of named fonts — or to register client fonts that aren't on any CDN and lock every picker to them — see the Brand Kit.

What gets stored and rendered

The picker stores the font slug (e.g. 'inter', 'merriweather', 'system-sans'). At render time Font::resolveFamily($slug) expands it to the full CSS font stack via the cached FontCatalog — so the CSS variable receives something like "Inter", ui-sans-serif, sans-serif.

Reading the setting through settings->get() returns a FontValue wrapping the stored value — Stringable, with a ->family property and a cssFamily() helper that quotes multi-word family names. For the Bunny stylesheet URL of a slug there's a static helper:

php
use FilamentCraft\Settings\Types\Font;

Font::remoteCssUrl('inter');
// "https://fonts.bunny.net/css?family=inter:400,500,600,700&display=swap"
// null for system stacks and unknown slugs

Free-form values pass through unchanged, so a theme author can ship a literal stack and skip the catalog entirely:

php
Font::make('brand')->default('"Acme Sans", sans-serif');

System stacks (system-sans, system-serif, system-mono) resolve entirely to platform fonts and emit no Bunny <link> tag. Any other family auto-injects:

html
<link rel="stylesheet"
      href="https://fonts.bunny.net/css?family={slug}:400,500,600,700&display=swap">

Catalog extension points

HookPurpose
->registerFont(BrandFont::make(...))Add a self-hosted or web-safe brand font to the picker — see Brand Kit.
\FilamentCraft\Support\FontCatalogThe catalog service singleton — bind your own implementation to swap the data source (e.g. self-host the list).
app(FontCatalog::class)->flush()Clear the 24-hour cache to force a fresh fetch.