Skip to content

Installation

Abdulkader Safi edited this page Aug 18, 2026 · 7 revisions

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.

1. Install the package

composer require safi/filament-atelier

On Packagist as safi/filament-atelier. Use dev-main instead of a tag if you want to track the branch.

2. Publish and migrate

php artisan vendor:publish --tag=filament-atelier-config
php artisan vendor:publish --tag=filament-atelier-migrations
php artisan migrate
php artisan storage:link

⚠️ storage: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.

3. Register the plugin

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.

4. Point Tailwind at the block views

⚠️ Required, and it fails silently. Skip it and every block renders unstyled, with no error in the console, the log, or anywhere else. Tailwind scans source files, and it has no idea your vendor directory exists.

In resources/css/app.css:

@source '../../vendor/safi/filament-atelier/resources/views/**/*.blade.php';

Then:

npm run build

If you write your own blocks, their views live in your app and Tailwind already scans those.

Using your own layout

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>

⚠️ Both failures are silent, and this is the third one on this page. Without 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 Arabic loses its font stack.

5. Decide what owns /

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.

6. Configure locales

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. If the site is English-only, delete the Arabic line now.

7. Optional: demo content

php artisan tinker --execute='(new Safi\Atelier\Database\Seeders\AtelierDemoSeeder)->run();'

Creates Home, About and a draft Contact in both languages, so you can see the thing working before you write anything. Delete them once you have real pages.

Verify it worked

php artisan route:list | grep atelier

You 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.

Upgrading an existing install

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 migrate

vendor: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.

⚠️ Skipping it fails late, not loudly. The package installs fine, the panel loads fine, and the missing table only surfaces as 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.

Releases that need it

Release What it adds
v0.1.2 atelier_page_revisions, the snapshot written on every publish.

What next

  • 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

Configuration reference

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.

Known limits

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.
  • Arabic shares the section order with English. 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.

Clone this wiki locally