Skip to content

Changelog

All notable changes to FilamentCraft are documented here.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

[Unreleased]

Added

  • Dual Filament 4 + 5 / Livewire 3 + 4 support. composer.json constraints broadened to filament/filament: ^4.0|^5.0, livewire/livewire: ^3.0|^4.0, pestphp/pest: ^3.0|^4.0, pestphp/pest-plugin-laravel: ^3.0|^4.0 and pestphp/pest-plugin-livewire: ^3.0|^4.0. Filament v5 ships zero API changes versus v4 (it only exists to allow Livewire 4); the editor's JS now uses the version-agnostic Livewire.hook('morph.updated', …) API alongside the legacy document.addEventListener('livewire:morph.updated', …) listener so post-DOM-patch reboots fire on both Livewire 3 and 4. phpunit.xml.dist sets a deterministic APP_KEY so Laravel 12 + Pest 4 boots without an encryption-key error. CI matrix in tests.yml runs the full Pest suite against both Filament/Livewire pairs (with filament/blueprint auto-removed on the v5 leg, since Blueprint v1.x caps filament/support at ^4.0).

  • Custom dynamic pages — four idiomatic doors, one shell. Host apps can now render any non-template page (cart, checkout, account, lesson player, search results, blog comments, gated downloads) inside the same theme + header region + footer region + fonts + tokens that FilamentCraft templates use. Each adopter picks the door that matches their style:

    • #[Storefront] Livewire attributeFilamentCraft\Attributes\Storefront extends Livewire\Attributes\Layout with the layout name pre-set. Drop it on any full-page Livewire component for zero-ceremony shell wrapping. The raw #[Layout('filamentcraft::layout')] form also works.
    • Route::filamentCraftStorefront(Owner::class, fn () => …) route macro — registers prefix + tenant middleware + Site binding for a whole group in one line. Reads the owner model from filamentcraft.tenancy.owner_model when omitted.
    • <x-filamentcraft::layout> Blade component — the explicit escape hatch with full prop control (:site, :title, :color-scheme, :mode, :locale). Aliasable via Blade::component('your-name', Layout::class).
    • Laravel Folio integrationphp artisan filamentcraft:install --folio scaffolds a starter resources/views/storefront/cart.blade.php and prints the FolioServiceProvider wiring. Zero PHP boilerplate per page after that.
  • ResolveSiteFromTenant middleware (alias filamentcraft.tenant) — resolves the current tenant from a route-param slug, sets it as the Filament tenant when a panel is bootable, and binds the matching live Site to the container. Config-driven so 'filamentcraft.tenant' with no arguments works when filamentcraft.tenancy.owner_model is set.

  • TenantSiteResolver (src/Resolvers/) — singleton that centralises "owner-by-slug → Filament::setTenant() → live Site-by-morph" so the middleware and the Layout component's URL fallback share one implementation instead of duplicating ~30 lines each.

  • Site::forOwner(Model $owner) local scope — polymorphic owner-match helper used by the resolver, replacing two raw ->where('owner_type', …)->where('owner_id', …) chains.

  • TemplateRenderer::buildShell() — extracted public method that returns the shell payload (tokens, header, footer, stylesheets, scripts, fonts, locale, dir, color scheme). Both renderPayload() and the new Layout component funnel through it so there's a single source of truth for the document chrome.

  • Auto-scroll preview on section selection. Opening a section in the editor sidebar (or visiting an editor URL with ?section=…) now smooth- scrolls the preview iframe to that section, using Livewire's morph.updated hook (version-agnostic) for post-patch reboots. Visibility-guard in the iframe handler suppresses the scroll if the section is already in the upper half of the viewport, so clicking a section inside the iframe doesn't snap-back. Consecutive same-id selections are deduped parent-side to skip the per-iframe postMessage fan-out.

Fixed

  • Editor sidebar resize stopped working after page morphs. layout-resize.ts keyed split-grid instances on the body element only — when Livewire / Filament navigation morphed the page tree and replaced the [data-fc-layout-gutter] node, the resize handle silently lost its mousedown listener. Now tracks the gutter element identity in a parallel gutterByBody WeakMap and rebinds when it changes.

  • Route::filamentCraftTenant() shadowed Filament /admin/* routes. The default tenantPattern was ^(?!admin$)[A-Za-z0-9-]+. Because PHP regex $ anchors to end-of-input (the whole URL path), the negative lookahead only blocked the literal segment admin — multi-segment URLs like /admin/acme passed the lookahead, the FC tenant route captured tenantSlug=admin + path=acme, and every Filament panel route at /admin/{tenant}/... 404'd in real integrations. Default pattern is now ^(?!admin\b)[A-Za-z0-9-]+ (word boundary), which correctly rejects both the bare admin segment and admin/anything. Hosts that mount Filament at a non-default path should pass a custom tenantPattern to the macro that excludes their panel prefix too — see docs/guides/custom-dynamic-pages.md §Gotchas. New regression test in tests/Feature/Routing/AdminRouteCoexistenceTest.php.

Changed

  • <title> in filamentcraft::renderer.layout now accepts an optional $title variable, falling back to $site->name (used by the new Layout component for per-page titles in dynamic pages). No behaviour change for existing template renders.

  • PHPStan grew a phpstan-bootstrap.php that registers the filamentcraft:: view namespace + the Route::filamentCraftTenant() and Route::filamentCraftStorefront() macros at analysis time, so namespaced view paths and macro calls resolve cleanly without per-file @phpstan-ignore noise.

Known caveats

  • The v5 + Livewire 4 PHPStan leg is currently marked continue-on-error in static.yml. Pest 4 + Livewire 4 ship stricter generic stubs whose @template TComponent does not propagate through the Livewire facade's @method static test() declaration, surfacing ~26 false-positive errors in test files (Unable to resolve template type, #[Computed] properties missing on instance()). The Filament 4 + Livewire 3 leg remains the strict static-analysis gate. Tracking upstream: re-enable the v5 PHPStan gate once larastan/larastan-livewire ships v4 support or the Livewire facade propagates the template parameter.

  • The --folio install flag scaffolds the starter file and prints the FolioServiceProvider snippet but does NOT auto-edit the host's service provider — Folio's path/uri/middleware wiring is currently a copy- paste step. Track for full automation once a Folio adopter asks.

Tests

  • 719 / 3098 (was 692 / 3041 in 0.1.0). New coverage: layout component rendering + alias support + custom-title + colour-scheme, ResolveSiteFromTenant middleware happy path + config defaults + not-found cases + invalid-owner errors, Route::filamentCraftStorefront route macro behaviour, URL-parameter fallback inside the Layout component with and without custom param names, #[Layout] and #[Storefront] attribute rendering through Livewire's full-page pipeline, --folio flag warning path. v4 leg PHPStan-clean, v5 leg test-clean.

[0.1.0] — 2026-05-12

First public release. Covers phases 0–6 of the master plan.

Added

  • ScaffoldingFilamentCraftServiceProvider, FilamentCraftPlugin, package config, install command, stubs.
  • Data layer + tenancySite, Theme, Template, TemplateRevision, Region Eloquent models with circular FK split (templates ↔ revisions); TenancyResolver that works without a tenancy package; SiteStatus, TemplateStatus, TemplateType, RegionName, Device enums.
  • Section DSL + registry + transformersAbstractSection, BladeSection, LivewireSection, Setting value object, Field descriptors, SectionRegistry, JSON ↔ runtime transformers, locale buckets.
  • Public renderer + fragment cacheTemplateResolver (exact + dynamic routes), TemplateRenderer with per-section fragment caching, Region rendering, PublicSiteController, SiteContext middleware.
  • Livewire editor shellEditorPage, plus Livewire components Topbar, SectionList, SettingsPanel, Canvas, AddSectionModal, PresetPicker; DraftStore, UndoStack, TemplateState, LocaleBucket, BroadcastPayloadBuilder, AutoSavePreference.
  • Iframe preview + postMessage bus + morphdomEditor/Protocol/Message + MessageType; resources/js/postmessage-bus.ts, iframe-injected.ts, editor.ts, keybindings.ts, layout-resize.ts, protocol.ts, tooltips.ts; AllowSameOriginIframe and InjectEditorScript middleware; PreviewController, SectionRefreshController, TemplateRefreshController.
  • Filament resourcesSiteResource, TemplateResource, ThemeResource (each with List / Create / Edit pages), the FilamentCraftDashboard page, and the form components ColorSchemeTokensField, ColorSchemeGroupField, ColorSchemeGroupEditor, ColorSchemePicker, FontPickerField, IconPicker, TemplateUrlPicker.
  • BlueprintsAbstractBlueprint, BlueprintRegistry, BlueprintSection, BlueprintSeeder, SeedResult, filamentcraft:seed-blueprints artisan command, plugin-level registration API, locked / hidden section flags with sealed-list guards.
  • ThemingThemeRegistry, ThemeContract, filamentcraft:sync-themes command, default token sets, font-picker integration with Bunny Fonts.
  • Multi-localeLocales helper, LocaleAwareSections state slice, empty-state UX (sidebar hint + canvas card), built-in Header section with locale switcher.
  • Built-in section catalogHeader section with mobile-safe wrapping classes.
  • Make commandsfilamentcraft:make-section, filamentcraft:make-theme.
  • Testing & gate — Orchestra Testbench base case, in-memory SQLite, 692 Pest unit + feature tests at 3043 assertions; Pint + PHPStan level 6
    • Pest wired through composer check; CI workflows for tests, static analysis, and committed JS/CSS dist parity.
  • Demo app integration — end-to-end browser test suite running against filamentcraft-demo via Pest 4 + pest-plugin-browser, covering the editor shell, save / publish, section CRUD, drag reorder at 3 viewports, device switcher, keyboard shortcuts, layout resize, breakpoints, file upload, public renderer, multi-tenant isolation, and locked / hidden Blueprint sections.

Notes

  • This release ships without Anystack licence enforcement. The soft-degrade SDK + UX will land in 0.2.0. Until then the package is delivered as-is via the path repository in filamentcraft-demo for internal verification.
  • Documentation (filamentcraft.dev/docs) is not part of this release.

Proprietary — distributed via Anystack.