Разработка · 7 мин чтения

Laravel Filament: как собрать админку на готовых компонентах

Когда в проект на Laravel нужна админка, я почти всегда предлагаю Laravel Filament вместо кастомной панели с нуля. За практику собрал на этом стеке больше десятка панелей: от списка заказов с фильтрами и экспортом до личного кабинета менеджера с ролями и виджетами статистики. Покажу, из чего состоит Filament, как я собираю первый ресурс и где он упирается в потолок, после которого нужна ручная доработка.

Что даёт Filament при разработке админки на Laravel

Filament работает поверх Laravel, Livewire и Tailwind CSS: он не рисует HTML руками, а собирает интерфейс из PHP-классов, которые описывают форму, таблицу и права доступа. Для админки это снимает целый пласт работы, который при самописном варианте съедает больше всего времени.

Обычная кастомная админка требует отдельного API для CRUD-операций, фронтенда поверх него (React, Vue или Blade с формами) и синхронизации состояния между ними. В Filament это один слой: класс-ресурс на PHP описывает и форму, и таблицу, и права, а Livewire сам обновляет интерфейс без перезагрузки страницы и без отдельного API.

На практике разница заметна по времени. Простой ресурс, форма из десятка полей и таблица с поиском и фильтрами, собираю за 2-3 часа, включая проверку на реальных данных. Тот же результат на кастомной React-админке с отдельным API занимает минимум день-два только на CRUD, без учёта аутентификации и прав доступа. На проектах, где внедряю Filament, обычно набегает от 10 до 30 ресурсов: товары, заказы, категории, пользователи, купоны, а иногда и таблицы для интеграций вроде логов вебхуков от CRM или банка.

Из каких блоков собрана Filament-панель администратора

Filament-панель состоит из нескольких типов блоков, и разобраться в них до старта работы стоит, чтобы не изобретать то, что уже есть готовым.

  • Panel: сама админка как приложение, путь /admin, тема оформления, список подключённых ресурсов и виджетов.
  • Resource: CRUD вокруг одной Eloquent-модели, список, создание, редактирование, просмотр.
  • Forms: набор полей формы, текстовые поля, select с поиском, загрузка файлов, редактор, повторяющиеся блоки для связанных данных.
  • Tables: колонки, сортировка, фильтры, поиск, массовые действия над выбранными строками.
  • Widgets: блоки статистики и графиков на главной странице панели или внутри ресурса.
  • Relation Managers: вкладки со связанными записями, например список позиций внутри карточки заказа.

Каждый из этих блоков представляет собой обычный PHP-класс с методами, которые возвращают массив конфигурации. Верстать вручную ничего не нужно, разве что стили для совсем нестандартных случаев.

Виджеты собираю так же декларативно. StatsOverviewWidget с тремя карточками, сумма продаж за месяц, число новых заказов, средний чек, показываю прямо на главной странице панели, данные забираю обычным Eloquent-запросом внутри метода getStats(). Для графика подключаю ChartWidget и возвращаю массив точек, ось X и Y Filament рисует сам.

Как я собираю первый CRUD-ресурс в Filament

Разворачиваю Filament в проект в несколько команд:

composer require filament/filament:"^5.0"
php artisan filament:install --panels
php artisan make:filament-user
php artisan make:filament-resource Post --generate

Команда filament:install - panels создаёт провайдер панели и публикует базовую конфигурацию. make:filament-user заводит первого пользователя с доступом в /admin. Если в базе уже есть таблица posts, make:filament-resource Post - generate строит форму и таблицу автоматически, опираясь на структуру колонок, останется только поправить типы полей вручную.

Готовый ресурс для модели с заголовком, текстом и флагом публикации выглядит так. По умолчанию Filament 5 раскладывает ресурс по подпапкам, форма уезжает в класс в Schemas, таблица в Tables, но описать их можно и прямо в ресурсе:

<?php

namespace App\Filament\Resources\Posts;

use App\Models\Post;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table;

class PostResource extends Resource
{
    protected static ?string $model = Post::class;

    public static function form(Schema $schema): Schema
    {
        return $schema->components([
            TextInput::make('title')
                ->required()
                ->maxLength(255),
            RichEditor::make('body'),
            Toggle::make('is_published'),
        ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('title')->searchable(),
                IconColumn::make('is_published')->boolean(),
                TextColumn::make('created_at')->dateTime(),
            ])
            ->filters([
                TernaryFilter::make('is_published'),
            ]);
    }
}

Дальше донастраиваю валидацию: required, maxLength, unique с игнорированием текущей записи при редактировании, default для полей со значением по умолчанию. Это методы прямо на компоненте формы, без отдельного FormRequest, хотя для сложной бизнес-логики всё равно выношу проверки в правила модели или сервис, чтобы они действовали не только в админке.

Связи между таблицами

Для связей у Filament есть готовые компоненты. Select::make('category_id')->relationship('category', 'name')->searchable() строит выпадающий список из связанной модели с поиском по названию, без ручного запроса в контроллере. Для связи «многие ко многим», например теги у поста, есть CheckboxList или отдельный Relation Manager, если список тегов длинный и его удобнее показывать отдельной вкладкой, а не внутри формы.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Кастомизация Filament: связи, экшены и права доступа

Штатных полей и колонок хватает на большинство задач. Остальное закрывается кастомизацией на том же PHP, без выхода в отдельный фронтенд.

Кастомные действия. Action::make('confirm')->label('Подтвердить заказ')->action(fn ($record) => $record->update(['status' => 'confirmed'])) добавляет кнопку в таблицу или карточку записи с произвольной логикой, а следом Notification::make()->title('Заказ подтверждён')->success()->send() показывает уведомление после выполнения.

Права доступа. Filament подключается к обычным Laravel-политикам (Policy): если у модели есть метод update в политике, кнопка редактирования в панели появится только у пользователей, которым это разрешено. Для ролей поверх политик обычно беру пакет Spatie Laravel Permission, он не завязан на Filament и работает как отдельный слой прав в приложении.

Кастомные страницы. Когда сценарий не укладывается в CRUD, например одна форма с настройками магазина без таблицы, не тяну её через Resource, а делаю отдельный Page-класс со своим шаблоном и методом сохранения. Это тот случай, где штатного ресурса на самом деле недостаточно и нужна явная доработка, а не обход ограничений.

Импорт и экспорт. Для выгрузки данных в Excel в Filament есть готовый ExportAction, для загрузки, соответственно, ImportAction с маппингом колонок файла на поля модели. Настраиваю через них массовую загрузку прайсов и каталогов, если данные приходят от поставщика таблицами.

Filament или своя админка на React: что выбрать

Filament закрывает внутренние панели и CRM быстрее, но не заменяет полноценный SPA-фронтенд, если админке нужен нестандартный UI под конкретный бренд или сложные пользовательские сценарии за пределами форм и таблиц. Сравниваю, что беру для каждого случая.

Критерий Filament Своя админка на React или Vue
Время на первый CRUD-экран часы от одного дня с учётом API
Нужен отдельный API нет, работает напрямую с Eloquent да, REST или GraphQL слой
Гибкость интерфейса ограничена компонентами и темой Tailwind любая, но её нужно верстать самому
Кто обслуживает Laravel-разработчик отдельно бэкенд и фронтенд разработчик

По деньгам разница ощутимая. Бэкенд на Laravel с админкой на Filament я оцениваю как разработку бэкенда на Laravel, от 100 000 рублей, панель входит в эту же работу. Отдельная CRM-панель на React, для которой Laravel-часть ещё нужно довести до полноценного API, стоит от 100 000 рублей уже без учёта самого API, то есть суммарно дороже за счёт двух слоёв вместо одного.

Сколько стоит внедрение Filament в проект на Laravel

Стоимость внедрения Filament зависит от того, что уже есть в проекте.

Если бэкенда ещё нет, оцениваю задачу как разработку API или бэкенда на Laravel целиком, от 100 000 рублей, туда входит и структура базы, и админ-панель на Filament поверх неё.

Если Laravel-проект уже есть и нужно добавить админку или несколько ресурсов в существующую Filament-панель, это точечная задача, беру такие правки почасово, от 3 000 рублей за час.

Когда нужно только обсудить архитектуру: какие ресурсы выделить, где нужны кастомные страницы, как разграничить роли, начинаю с консультации, от 3 000 рублей.

Laravel регулярно обновляется, поэтому перед внедрением я сверяюсь с актуальной документацией.

Частые вопросы

Чем Filament отличается от Laravel Nova

Nova тоже официальный пакет для админ-панелей от команды Laravel, но распространяется по платной лицензии. Filament открытый исходный код и бесплатен в использовании, а по набору компонентов, форм, таблиц и виджетов они во многом похожи. Выбираю Filament, чтобы не привязывать стоимость проекта к лицензии стороннего пакета.

Нужно ли знать Livewire, чтобы работать с Filament

Для стандартных ресурсов нет, вся работа идёт через PHP-классы и готовые компоненты форм и таблиц, без написания Livewire-кода руками. Livewire пригодится, если нужен полностью кастомный компонент со своей логикой на странице, тогда без понимания его жизненного цикла не обойтись.

Можно ли ограничить доступ к части данных в Filament

Да, через обычные Laravel-политики: доступ к ресурсу, кнопкам и отдельным записям Filament проверяет через методы политики модели. Роли поверх этого обычно строю на Spatie Laravel Permission, а если нужна многотенантность, когда разные клиенты видят только свои данные, у Filament есть отдельный механизм панелей с таким разделением.

Подходит ли Filament для интернет-магазина

Да, но именно для управляющей части: каталог, заказы, склад, покупатели. Публичная витрина магазина, которую видят покупатели, это отдельный фронтенд, Filament для неё не предназначен, он закрывает только внутреннюю панель управления поверх тех же Eloquent-моделей, что использует витрина.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно