Поля панели Filament
Бесплатный пакет rankbeam/laravel-seo-filament добавляет полноценный SEO-раздел в форму любого ресурса Filament — две строки на ресурс. Поддерживаются Filament 4.x и 5.x (Livewire 3 и 4). Редактирование метаданных бесплатно; Pro добавляет сканирование и оценку, показанную в примере ниже.
Предварительные требования
Используйте существующую панель Filament 4 или 5 и модель с трейтом HasSEO ядра. Перед добавлением редактора пройдите быстрый старт ядра, включая миграции и вывод.
Установка
composer require rankbeam/laravel-seo-filamentМодель ресурса должна использовать трейт HasSEO ядра.
Добавление раздела в ресурс
use Rankbeam\Seo\Filament\Concerns\HasSEOFields;
class PostResource extends Resource
{
use HasSEOFields; // 1
public static function form(Schema $schema): Schema
{
return $schema->components([
TextInput::make('title'),
// ...
static::seoSection(), // 2
]);
}
}Проверка сохранённого результата
Откройте существующую запись. Введите SEO-описание, сохраните и перезагрузите форму. Значение должно сохраниться и появиться в предпросмотре, а источник должен показывать Вручную. Проверьте <head> отрендеренной страницы, чтобы убедиться, что посетители получают то же описание.

Пример из демо Merchant. Поля используют тему вашей панели; доступные элементы управления и лимиты символов зависят от установленной версии и конфигурации.
Раздел включает:
- Заголовок и описание с живыми счётчиками символов. Лимит задаёт политика длины ядра для вводимой письменности: 60/160 для латиницы, около 30/80 для CJK, с подсчётом графем.
- Ключевые слова — поле тегов. Вы вводите обычные ключевые слова; они сохраняются в структурированном формате ядра
[{keyword, is_primary}](первое считается основным), поэтомуgetPrimaryKeyword()иSEODataчитают их без изменений. Включитеseo.keywords.enabled, чтобы командаseo:auditи сканирование Pro отмечали страницы без ключевого слова. По умолчанию выключено; используется один переключатель, см. Конфигурация. - Canonical-URL (пусто = автоматически, без строки запроса).
- Список Директива robots (пусто = значение сайта по умолчанию).
- Загрузку изображения для соцсетей (og:image / twitter:image), сохраняемого на диске Filament по умолчанию в
seo/. - Предпросмотр результата поиска, который во время ввода отражает цепочку резервных значений резолвера.
- Индикаторы источников: какой уровень резолвера дал фактическое значение каждого поля — Вручную, Из контента, Значение по умолчанию для типа модели, Глобальное значение по умолчанию, Конфигурация сайта или Получено из URL.
Ограничение набора полей
static::seoSection(['title', 'description'])Принимается любое подмножество title, description, focus_keywords, canonical, robots, og_image.
Без трейта SEOFields::make(?array $only) возвращает тот же раздел напрямую.
Как сохраняются значения
Раздел привязывается к группе состояния seo_meta и сохраняется через связь seoMeta() ядра (обновление или создание). В ваших таблицах не появляются новые столбцы, а значения сразу становятся шестым, явным уровнем резолвера.
Несколько языков
Ядро хранит одну строку seo_meta на пару (модель, локаль). Передайте локали, на которых опубликована страница: раздел выведет вкладку для каждого языка (Filament 1.9):
static::seoSection(locales: ['en', 'it', 'ja']);
// or, without the trait
SEOFields::make(locales: ['en', 'it', 'ja']);Или задайте их один раз для всех ресурсов в конфигурации пакета:
php artisan vendor:publish --tag=seo-filament-config// config/seo-filament.php
'locales' => ['en', 'it', 'ja'],Каждая вкладка редактирует собственную строку и имеет свои:
- счётчики по политике длины для письменности языка: пустой японский заголовок показывает
0 / 30, а английская вкладка той же страницы —0 / 60; - предпросмотр поисковой выдачи и карточки соцсетей из итоговых значений этой локали;
- индикаторы резервных значений, описывающие строку этой локали;
- значок с количеством заполненных полей этой версии, чтобы пустые переводы были заметны.
При загруженном ext-intl вкладка подписывается названием языка на языке панели (Italiano / Italian), иначе — кодом. Все вкладки проходят валидацию и сохраняются вместе; для языка, в котором ничего не введено, строка-заглушка не создаётся.
Собственные привязки состояния формы
При нескольких локалях путь состояния — seo_meta.{locale}.title; при одной он остаётся seo_meta.title. Используйте соответствующий путь в собственных действиях формы.

Демо Merchant, 9 сентября 2026 года, с locales: ['en', 'it', 'ja']. Пустая японская вкладка использует собственные счётчики. Английский заголовок здесь взят из резервного контентного значения демо-модели: добавление языковой вкладки не переводит контент. Оценка Pro над полями — результат последнего сканирования записи, а не отдельная оценка каждой языковой вкладки.
С плагином переводов
При использовании lara-zeus/spatie-translatable 1.x на Filament 4 или 2.x на Filament 5 применяйте адаптеры страниц Rankbeam для Edit и Create. Замените только импорты трейтов страниц; оставьте трейты ресурсов и списков, плагин панели и действие LocaleSwitcher:
// In your EditPost page:
use Rankbeam\Seo\Filament\Resources\Pages\EditRecord\Concerns\Translatable;
// In your CreatePost page (a separate file):
use Rankbeam\Seo\Filament\Resources\Pages\CreateRecord\Concerns\Translatable;Каждая страница по-прежнему объявляет use Translatable; внутри класса. Плагин остаётся необязательной зависимостью приложения. Используйте его последнюю исправленную версию; локальная интеграционная фикстура покрывает плагин 1.0.4 / Filament 4.13.1 и плагин 2.0.1 / Filament 5.8.1.
При переключении в редакторе сохраняются несохранённый контент основной записи, SEO-метаданные и черновики структурированных данных. Сохранение проверяет каждый посещённый язык и записывает их вместе в транзакции базы данных. При ошибке валидации открывается требующий внимания язык. Загрузки записываются при сохранении; выход со страницы или её перезагрузка удаляет несохранённые черновики. Сохранение черновика не переводит недостающий контент.
Адаптеры сохраняют обычные хуки до и после операций и преобразователи данных формы. Если страница переопределяет handleRecordCreation(), handleRecordUpdate(), callHook() или методы транзакций, включите поведение адаптера в эту доработку и проверьте сохранение. Транзакции базы данных не откатывают запись в файловую систему; приложение должно сохранять обычную очистку файлов без связанных записей.
Для собственных живых текстовых полей на Livewire 3 предпочитайте ->live() или ->live(onBlur: true) явно заданному debounce: последний задерживает локальное состояние модели и может потерять последние нажатия при быстром переключении локали. Поля заголовка и описания Rankbeam используют стандартную задержку запросов.
Исходные трейты страниц плагина при переключении заново заполняют формы. Rankbeam защищает от их случайных записей метаданных, но эти трейты не сохраняют SEO-черновики; переведите страницы Edit/Create на адаптеры. Явные вкладки locales: остаются общим редактором и имеют приоритет над переключателем страницы.
Без явного списка локалей или локали страницы раздел редактирует локаль приложения.
Структурированные данные (schema.org)
Необязательный раздел Структурированные данные позволяет редакторам добавлять JSON-LD-разметку для расширенных результатов без изменения кода. Добавьте его рядом с SEO-разделом:
public static function form(Schema $schema): Schema
{
return $schema->components([
// ... your fields ...
static::seoSection(),
static::seoSchemaSection(), // optional
]);
}(или используйте SEOSchemaFields::make() напрямую, без трейта).
Он записывает данные в столбец ядра seo_meta.schema_jsonld — то же значение, которое выводит рендерер разметки, — и является только привязкой интерфейса: каждый документ создаётся построителем разметки ядра и перед сохранением проверяется SchemaValidator ядра. Собственной логики разметки он не добавляет.
Раздел предлагает:
- Автоматические хлебные крошки — один переключатель, представленный первым как возможность без настройки. Создаёт
BreadcrumbListиз цепочки родителей записи черезBreadcrumbSchema::fromModelAncestors(). Заполнять ничего не нужно: используются предки модели. - Блоки схемы — повторитель. Каждый блок представляет FAQ (пары вопрос/ответ →
FAQPage) или Товар (название, описание, изображение, бренд, SKU, цена и валюта, наличие →Product), создаваемые построителями ядраFAQSchema/ProductSchema.
Валидация
Блок, который сформировал бы некорректный JSON-LD, отклоняется при сохранении с сообщением валидатора ядра: например, FAQ без ответа или Product без изображения либо предложения. Эти поля требует данный построитель; это не полное описание требований Google для каждой поисковой функции Product. Пустые блоки просто игнорируются.
Что сохраняется
schema_jsonld содержит построенные документы: один объект, если документ один, или JSON-массив, если их несколько (сначала хлебные крошки, затем ваши блоки). Оба варианта — корректный JSON-LD, который без изменений выводится через @seo / renderSchema().
Разметка вне управления редактора
Разметка, написанная в коде и не представимая этим редактором, — собственный @graph, нестандартный @type или Product с полями, которых нет в форме (отзывы, рейтинги, GTIN/MPN), — сохраняется дословно. Открытие и сохранение формы её не затирают.
Устранение неполадок
- Сохранённого поля нет на странице: убедитесь, что шаблон выводит
@seo($model)для той же записи и локали. - Поле всё ещё использует резервное значение: проверьте, сохранено ли переопределение поля в активном языке. Индикаторы источников показывают итоговый уровень.
- Языковая вкладка отсутствует: проверьте явный аргумент
locales:, конфигурацию пакета и переключатель переводов страницы. Их приоритет описан выше.
Тестирование собственной панели в Testbench
Если вы загружаете Filament внутри orchestra/testbench, зарегистрируйте его SupportServiceProvider до LivewireServiceProvider. Filament заново привязывает DataStore Livewire, и неверный порядок ломает каждый тест Livewire с ошибкой ViewErrorBag::put(): ... null given. Реальные приложения не затронуты: автоматическое обнаружение пакетов правильно упорядочивает провайдеры.