statikbe/laravel-filament-flexible-content-blocks
A Laravel and Filament package for creating flexible, reusable content blocks. Define block types, manage page sections with a visual editor, and render dynamic layouts without hardcoding templates—ideal for CMS-style pages and maintainable content structure.
This package gives you a Filament form field, a set of Eloquent models, and Blade views for building "flexible content" pages — an ordered, repeatable list of typed blocks (text, image, video, CTA, etc.) attached to any model.
Minimum path to a first working page:
composer require statikbe/laravel-filament-flexible-content-blocks and confirm the package major matches your Filament major (v4.x targets the current Filament line — check the README compatibility table before upgrading an existing app).php artisan vendor:publish --tag=filament-flexible-content-blocks-config
php artisan vendor:publish --tag=filament-flexible-content-blocks-migrations
php artisan vendor:publish --tag=filament-flexible-content-blocks-views
php artisan migrate
Start by publishing only config + migrations. Publish views later, once you actually need to override markup — published views are yours to maintain and won't receive package updates.config/filament-flexible-content-blocks.php first. This is the real entry point: it defines which block types exist, their labels/icons, and how they map to views. Read it before reading any source.PageResource) — a ContentBlocks-style field that renders the block repeater with add/reorder/delete.renderContentBlocks() call on the model, e.g.:
<x-flexible-content-blocks::content-blocks :model="$page" />
(Confirm the exact component/renderer name in the README for your installed version — this is the one API surface that has historically shifted between majors.)First use case to build: a Page model with title, slug, and blocks, rendered by a catch-all route. That exercises the whole loop — migration, model trait/relation, Filament form, frontend rendering — in under an hour, and is the shape 90% of real usages take.
Treat block types as a registry, not as free-form content. Define your block set in config (or a backed enum, depending on version), each mapping to a Blade view in your published views directory. Keep one view per block type and keep them dumb: they receive the block model and render. This is what makes the package maintainable — adding a block type becomes "config entry + one Blade file + one Filament field", with no changes to the page resource.
Scope the field, don't globalise it. The content-blocks field belongs on models that genuinely need free-form composition. For structured content, keep normal columns. A common healthy split: hero/SEO fields as columns, long-form body as blocks.
Store the render in a partial, not in controllers. Put the block loop in resources/views/pages/show.blade.php calling a partials.blocks include. When you later add the Filament preview theme (see below) or an email/API renderer, you reuse the same partial.
Use the new Filament theme for in-panel preview (v4.2). This release adds a Filament theme for rendering content blocks inside Filament, so editors see something closer to the real frontend output in the admin panel instead of raw form fields. Practical integration:
->theme() / Vite theme configuration, or by adding the package's Tailwind preset to your admin CSS entry — the README shows the current wiring).content globs include the published block views, otherwise previews render unstyled.npm run build (or vite build) plus php artisan filament:assets.Localisation. If your site is multilingual, wire the package's translated fields (title/text per locale) and render with the active locale. Keep a fallback locale configured; blocks with an empty translation are the most common source of blank sections in production.
Media and images. Block image fields are typically backed by a media library integration. Always eager load the media relation when rendering a list of pages, and generate responsive conversions rather than outputting originals.
Ordering and caching. Because block order is data, any full-page HTML cache must be invalidated on block save/reorder — hook the model events rather than relying on TTL.
Testing. Assert on the rendered HTML of the block partial for a fixture page rather than asserting on package internals; the package's own view layer is the part most likely to change between releases.
content globs. Add the package views path and your published views to tailwind.config.js before debugging why a block looks unstyled — this is the single most common first-day issue.vendor:publish --tag=...-views, package view fixes no longer reach you. Keep the publish step late, note the package version in a comment at the top of overridden files, and re-diff on upgrade.php artisan filament:assets and clear view:clear / config:clear after upgrading, and rebuild your own Vite bundle. Stale compiled assets look exactly like a code bug.php artisan config:clear after every registry change; a cached config with a removed block type produces confusing "view not found" errors.^4.2 in composer.json and upgrade majors deliberately with a full form/render regression pass.How can I help you explore Laravel packages today?