Live Preview
Editing any setting in the editor patches the preview iframe in place. This page explains the two live-update modes, what the iframe does per change, and where values are stored.
Live-update modes
The SchemaCompiler routes every field through one of two Livewire live modes. You don't configure this — it's chosen automatically per setting type.
- Instant
live()— the round-trip fires on every change. Used for discrete, one-click inputs:Checkbox,Radio,EnumButtons,Select,ColorScheme,Font,Icon. - Lazy
live(onBlur: true)— the round-trip is deferred until the field loses focus. Used for typed, dragged, or uploaded inputs where a half-finished value shouldn't trigger a re-render mid-edit:Text,Textarea,Number,Range,Color,Image,Link,RichText.
The lazy mode is load-bearing for RichText: Filament v4's TipTap editor throws if Livewire morphs the surrounding DOM mid-keystroke, so its round-trip is always deferred to blur.
What the iframe does per change
| Change | What the iframe does |
|---|---|
| Active color scheme slug only | Flips data-fc-color-scheme on <html> instantly — no server round-trip, because every scheme's tokens are pre-rendered into <style id="fc-tokens">. |
| Authored color tokens, font slug, range / checkbox / etc. | Requests a server templateRefresh (single GET, ~150 ms), then morphs <body> and re-syncs <head>: the <style id="fc-tokens"> text is replaced, stale Bunny <link> tags are pruned, and fresh ones added. No flash, no FOUC for cached fonts. |
| Section settings (e.g. a Hero heading) | Either patched in place via the LivePatcher (any element with data-fc-live="…" gets a surgical update) or via a section-level refresh, depending on the field shape. |
Fonts in the live loop
The renderer auto-injects a Bunny Fonts stylesheet for every Font setting whose value resolves to a remote family:
<link rel="stylesheet"
href="https://fonts.bunny.net/css?family={slug}:400,500,600,700&display=swap">System stacks (system-sans, system-serif, system-mono) emit no <link> because they resolve entirely to platform fonts. See Font Picker for details.
Persistence
Where values live once you save:
- Active color scheme slug — on the template draft, so different templates can use different schemes.
- User-authored color schemes (Add scheme + 22 tokens) — on
Site.settings_json['schemes'], kept separate from the 14 package-shipped built-ins. - Every other theme setting value — on
Site.settings_json, keyed by setting id. Writes are diff-only: a value matching its schema default isn't stamped, so unset values inherit the schema's default and package upgrades to those defaults flow through automatically.
Programmatic read/write (migrations, seeds, API endpoints):
use FilamentCraft\Support\SiteThemeSettings;
use FilamentCraft\Support\SiteColorSchemes;
// Read merged values (overrides + schema defaults).
$values = SiteThemeSettings::values($site, $site->theme->templateSettings());
// Write a partial set (diffs against defaults).
SiteThemeSettings::sync($site, $schema, ['button_radius' => 12]);
// Color-scheme overrides (per-site authored map).
$schemes = SiteColorSchemes::forSite($site); // 14 built-ins + overrides
SiteColorSchemes::add($site, cloneFrom: 'cupcake'); // returns "scheme-N"
SiteColorSchemes::remove($site, 'scheme-13');Related
- The Editor — the editing UI as a whole.
- Setting Types — the per-type live-mode summary.
- Color Schemes — the scheme system the first row above relies on.
