• Fabricator
  • Fabricator
  • Fabricator


Plugin information

by Z3d0X

Admin panel Developer tool Kit

Block-Based Page Builder Skeleton for your Filament Apps


#fabricator on Discord







What is Filament Fabricator? Filament Fabricator is simply said a block-based page builder skeleton. Filament Fabricator takes care of the PageResource & frontend routing, so you can focus on what really matters: your Layouts & Page Blocks.

If you are a visual learner checkout this video.


Once you have Filament Admin Panel configured. You can install this package via composer:

composer require z3d0x/filament-fabricator

After that run the install command: (this will publish the config & migrations)

php artisan filament-fabricator:install

To get started create a Layout and then Page Blocks


Creating a Layout

Use the following command to create a new Layout:

php artisan filament-fabricator:layout DefaultLayout

This will create the following Layout class:

use Z3d0X\FilamentFabricator\Layouts\Layout;
class DefaultLayout extends Layout
protected static ?string $name = 'default';

and its corresponding blade component:

<x-filament-fabricator::layouts.base :title="$page->title">
{{-- Header Here --}}
<x-filament-fabricator::page-blocks :blocks="$page->blocks" />
{{-- Footer Here --}}

You may edit this layout blade file however you want, as long as you are using the filament-fabricator::page-blocks to show the page blocks

Pro Tip 💡: Use the $page instance to build your layout

Base Layouts

You may noticed that layouts created are wrapped in a filament-fabricator::layouts.base component. This is the Base Layout. You can use the following, in the boot() of a ServiceProvider, to inject additional data to the base layout:

use Z3d0X\FilamentFabricator\Facades\FilamentFabricator;
use Illuminate\Foundation\Vite;
//Add custom tags (like `<meta>` & `<link>`)
new HtmlString('<link rel="manifest" href="/site.webmanifest" />'),
//Register scripts
'https://unpkg.com/browse/[email protected]/dist/tippy.esm.js', //external url
mix('js/app.js'), //laravel-mix
app(Vite::class)('resources/css/app.js'), //vite
asset('js/app.js'), // asset from public folder
//Register styles
'https://unpkg.com/tippy.js@6/dist/tippy.css', //external url
mix('css/app.css'), //laravel-mix
app(Vite::class)('resources/css/app.css'), //vite
asset('css/app.css'), // asset from public folder

Apart from these this plugin also adds the following Filament's Render Hooks to the base layout:

  • filament-fabricator.head.start - after <head>
  • filament-fabricator.head.end - before </head>
  • filament-fabricator.body.start - after <body>
  • filament-fabricator.body.end - before </body>
  • filament-fabricator.scripts.start - before scripts are defined
  • filament-fabricator.scripts.end - after scripts are defined

Pro Tip 💡: Using a base layout is completely optional, if you don't need it you may just remove it from the generated layout blade file. If you prefer, You may also use your own base layout.

Page Blocks

Creating a Page Block

Use the following command to create a new Page Block:

php artisan filament-fabricator:block MyBlock

This will create the following Page Block class (& its corresponding blade component view):

use Filament\Forms\Components\Builder\Block;
use Z3d0X\FilamentFabricator\PageBlocks\PageBlock;
class MyBlock extends PageBlock
public static function getBlockSchema(): Block
return Block::make('my-block')
public static function mutateData(array $data): array
return $data;

Pro Tip 💡: You can access the $page instance in the block, by using the @aware blade directive

{{-- `my-block.blade.php` --}}
@aware(['page']) // make sure this line exists, in order to access `$page`

Page Block Schema

Define you block schema in this method:

public static function getBlockSchema(): Block

You may use any Fields to make up your schema.

Pro Tip 💡: You can conditionally allow blocks based on a layout using:

->visible(fn ($get) => $get('../layout') == 'special')

Mutate Data

By default, your blade component will receive raw data from all the fields as props


//Given the following schema
public static function getBlockSchema(): Block
return Block::make('my-block')
{{-- Your blade component would receive the following props --}}

However you may customize this behavior using:

//`$data` is the raw block data.
public static function mutateData(array $data): array

The array keys from this would be your blade component props.


// `MyBlock.php`
public static function mutateData(array $data): array
return ['foo' => 'bar'];
{{--- `my-block.blade.php` --}}
@dump('foo') // 'bar'

Page Builder

Underneath the hood PageBuilder is just a Filament's Builder field. Like other filament fields this field also has methods that can be used to modify it. You may configure it like this:

use Z3d0X\FilamentFabricator\Forms\Components\PageBuilder;
PageBuilder::configureUsing(function (PageBuilder $builder) {
$builder->collapsible(); //You can use any method supported by the Builder field

Page Resource

Customize Navigation

You may use the following methods in the boot() of a ServiceProvider to customize the navigation item of PageResource

use Z3d0X\FilamentFabricator\Resources\PageResource;


To enforce policies, after generating a policy, you would need to register \Z3d0X\FilamentFabricator\Models\Page to use that policy in the AuthServiceProvider.

namespace App\Providers;
use App\Policies\PagePolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Z3d0X\FilamentFabricator\Models\Page;
class AuthServiceProvider extends ServiceProvider
protected $policies = [
Page::class => PagePolicy::class,

If you are using Shield just register the PagePolicy generated by it