-
Notifications
You must be signed in to change notification settings - Fork 0
Installation
Atelier needs PHP 8.3+, Laravel 12 or 13, Filament 5, and Tailwind 4 on the front end.
Three of these steps fail silently. They're marked.
composer require safi/filament-atelierOn Packagist as safi/filament-atelier. Use dev-main instead of a tag if you want to track the branch.
php artisan vendor:publish --tag=filament-atelier-config
php artisan vendor:publish --tag=filament-atelier-migrations
php artisan migrate
php artisan storage:linkstorage:link is not optional. Uploaded images go to the public disk. Without the symlink, every image in the builder and on the live site is a broken image, with no error anywhere to tell you why.
In your panel provider, usually app/Providers/Filament/AdminPanelProvider.php:
use Safi\Atelier\AtelierPlugin;
use Safi\Atelier\Blocks\DefaultBlocks;
->plugins([
AtelierPlugin::make()
->blocks(DefaultBlocks::all()),
])DefaultBlocks::all() is the set Atelier ships: hero, features, rich text, image, gallery, logo wall, testimonials, FAQ, call to action. Pass your own array to cherry-pick, and add your own classes alongside them.
In resources/css/app.css:
@source '../../vendor/safi/filament-atelier/resources/views/**/*.blade.php';Then:
npm run buildIf you write your own blocks, their views live in your app and Tailwind already scans those.
atelier.layout points at the Blade view wrapping the rendered blocks. Pointing it at your
own is the normal way to give a client site its own navigation and footer.
Your layout receives $blocks (the rendered HTML), $locale, $page, $title and
$preview. Include the two partials:
<!DOCTYPE html>
<html lang="{{ $locale }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{-- Title, description, canonical, hreflang, Open Graph, Twitter, and
noindex on previews. Emits its own <title>, so don't write one. --}}
@include('atelier::partials.meta')
@vite(['resources/css/app.css'])
{{-- Design tokens. After your stylesheet, so they win. --}}
@include('atelier::partials.tokens')
</head>
<body>
<header>Your navigation</header>
<main>{!! $blocks !!}</main>
<footer>Your footer</footer>
</body>
</html>partials.meta the page renders perfectly and carries no title, description, canonical,
hreflang or Open Graph tags, and previews stop being noindex. Without partials.tokens
every var(--atelier-*) resolves to nothing, so the background and spacing controls do
nothing and RTL locales lose their font stack.
Atelier registers a catch-all for /{slug} and /{locale}/{slug}. Your app's own routes are matched first, so nothing you already have breaks.
A fresh Laravel app has a welcome route on /. Remove it from routes/web.php if you want the CMS to own the home page, or the welcome screen keeps winning.
config/atelier.php:
'locales' => [
'en' => ['label' => 'English', 'dir' => 'ltr'],
'ar' => ['label' => 'العربية', 'dir' => 'rtl'],
],The first locale is the default and lives at /{slug}. Every other locale lives at /{locale}/{slug}.
Decide this before you create pages. Changing it later means migrating the per-locale maps inside every block tree on every page. The two shipped locales are a starting point, not a requirement: keep one, replace them, or add more. A single-locale site works fine and the language switcher hides itself.
php artisan tinker --execute='(new Safi\Atelier\Database\Seeders\AtelierDemoSeeder)->run();'Creates Home, About and a draft Contact in every configured locale, so you can see the thing working before you write anything. Delete them once you have real pages.
php artisan route:list | grep atelierYou should see the preview route, the editor page and the public page routes.
Then log into /admin, open Pages, and click a page. You should land on its settings, with an Edit page content button that opens the builder full screen.
If the builder loads but the preview iframe is blank or unstyled, check step 4, and check whether a stale public/hot file is pointing Vite at a dev server that isn't running.
New tables ship as new migration files, never as an edit to one that already ran on your database. So after every update:
composer update safi/filament-atelier
php artisan vendor:publish --tag=filament-atelier-migrations
php artisan migratevendor:publish skips files you already have, so this only ever copies what's new. It will
not overwrite a migration you have edited, and it will not re-run one that has already
migrated.
no such table: atelier_... the first time someone
uses the feature that needs it. Publishing migrations after an update costs two seconds and
is a no-op when there is nothing new.
Add --tag=filament-atelier-config to the same command if you want new config keys written
into your published config/atelier.php. That one will not touch your existing file,
so new keys fall back to their packaged defaults either way and re-publishing is optional.
CHANGELOG.md in the repository says which releases need a migration.
| Release | What it adds |
|---|---|
| v0.1.2 |
atelier_page_revisions, the snapshot written on every publish. |
- Usage, the editor and the day-to-day flow
- Blocks, writing your own section types
- Layouts, several shells with a per-page choice
- SEO, the sitemap and everything around it
- Troubleshooting, if something looks quietly wrong
The short version. Every key, with the reasoning, is on Configuration.
config/atelier.php:
| Key | What it does |
|---|---|
locales |
Which languages exist. First one is the default and has no URL prefix. |
layout |
The Blade layout wrapping rendered blocks. Both the preview and the public page use it. Point it at your own view and include the two partials, see above. |
preview.debounce |
Milliseconds after typing stops before the preview refreshes. |
preview.widths |
Pixel widths for the desktop, tablet and mobile switcher. |
preview.link_expiry_minutes |
How long a shareable preview link stays valid. |
media.disk |
Disk for uploads. Must be public. |
media.directory |
Folder within that disk. |
revisions.keep |
Snapshots kept per page. Pruned on publish. |
robots.disallow_panel |
Panel path to disallow in robots.txt. null leaves it crawlable. |
tokens |
Design token overrides. Anything you leave out falls back to the shipped palette, type, spacing and widths in Safi\Atelier\Tokens. |
Accurate as of 18 Aug 2026. CHANGELOG.md is the running record.
- Reordering is arrow buttons, not drag.
- New sections are added at the end. Moving one into the middle means clicking up.
- Block types are code only. Creating them from the panel is not built, and is v2.
- Translations share the section order with the default locale. One tree, translated text. Deliberate.
-
No revisions UI. Snapshots are written on every publish and
Page::restoreRevision()restores one into the draft, but there is no screen for browsing or comparing them yet. - No contact form handling. The block posts to a route you wire per site, by design.
Building
Running a site
Reference