Skip to content

Filament Atelier

The example app stopped using the blocks the package ships

13 September 2026 Updated 13 September 2026 3 min read
A file tree of the example application showing nine block classes beside nine matching Blade views.

The last request before tagging v0.5.0 was that someone opening the example folder should understand everything without reading the package. That meant the demo site defining all nine of its own sections, which sounded like duplication and turned out to be the most honest thing in the repository.

Atelier ships nine blocks: hero, features, rich text, image, gallery, logo wall, testimonials, FAQ, call to action. Register them with one line and a client can build a marketing site.

The example app used them, plus two of its own. Then came a request I initially read as duplication:

Instead of using the default blocks I want you to create custom blocks, because I want when someone opens the example folder he can understand everything, not needing to search for example blocks in the code of the package.

Why it is right

The example app is the only place a person can read a complete working site. Every time it borrows something from the package, understanding the site means opening two repositories in a mental split screen: this section is defined over there, its view is over there, but its data is here.

Worse, it made the example look like a consumer of a black box, when the entire promise of the package is that a block is one PHP class and one Blade view that you write. Demonstrating that by not writing any is a strange way to make the argument.

So the panel now registers exactly one list:

AtelierPlugin::make()
    ->blocks(SiteBlocks::all())

Nine classes in app/Blocks, nine views in resources/views/blocks, and nothing else decides what a page can hold. DefaultBlocks::all() is not called at all.

What that costs

Roughly 700 lines, most of it Blade. Every one of them is a line somebody can read without leaving the folder, and several of them are better than what the package ships because they are written for one brand rather than for everybody.

The hero class carries the fullest comments, because it is the one to read first: what type(), translatable(), defaults(), view() and schema() each decide, and why ->live(debounce: 400) is the difference between a preview that moves as you type and one that waits for you to click away.

Two things it broke

Four tests wanted an image block. The example's suite doubles as the package's, and the image upload tests add a block of type image, which the demo site does not have. They now register the package's block themselves:

// The panel registers this app's own blocks, and this site has no image
// block. These four tests cover the package's upload path, so they
// register the package's block to have something to upload into.
app(BlockRegistry::class)->register(ImageBlock::class);

Three lines of comment for one line of code, which is the correct ratio when the line exists because of a decision made somewhere else.

A picker test asserted a block that no longer exists. It checked that a page type narrows the section picker by looking for logo-wall being absent. There is no logo wall any more. The assertion now uses a block the site actually has, which is a better test anyway: it proves the narrowing with the site's own vocabulary.

What I would tell someone copying this

Do not do it in a client project. Start from DefaultBlocks::all() and add your own alongside, because nine free blocks are nine you do not maintain. The example is the one place where readability beats reuse, because being read is its entire job.

The SiteBlocks docblock says exactly that, so nobody takes the wrong lesson:

Deliberately not DefaultBlocks::all(). The package ships an equivalent set, and a real project usually starts from it, but this app defines its own so that everything on the site can be read in one folder without opening the package.

Where it stands

Shipped alongside v0.5.0. example/DEMO.md is a tour with a table of which file does what, a five-step trail through the panel and the public site, and the list of things the demo is deliberately demonstrating.

209 tests pass, the site runs, and the folder answers its own questions. A demo that needs a guided tour of another repository was not a demo, it was a screenshot with extra steps.