happenv-com/filament-translatable
Filament Translatable provides a complete solution for managing multilingual content in Filament admin panels, adding intuitive tabbed translatable form fields with multiple translation backends, configurable locales, and support for Filament 3, 4, and 5.
Architecture fit. The package slots into the standard Filament plugin contract (Panel::plugin()) and ships a form component (Happenv\FilamentTranslatable\Forms\Component\Translations) plus a fluent translatable() macro that any Filament field can adopt. That is the right shape for a Filament add-on: no service container overrides, no model base-class inheritance, no route or middleware interception. It is additive rather than invasive, which keeps it reversible. Crucially it is a presentation-layer package — it does not own persistence, and it delegates translation storage to spatie/laravel-translatable (default) or astrotomic/laravel-translatable. For a shop already standardized on Spatie, this is a near-zero-architecture-change adoption; for Astrotomic shops it requires swapping in the vendor's AstrotomicTranslatable trait, which is a model-layer commitment.
Integration feasibility. Mechanically simple: composer require, php artisan filament:assets, register the plugin with a locale array, convert a field. The locale list can be a closure (e.g. fn () => Language::pluck(...)), so locale administration can stay in the database rather than hard-coded config. Validation ergonomics (requiredLocale(), requiredDefaultLocale()) and per-locale field decoration (decorateTranslationField()) cover the two requests content teams most often raise. Estimated effort for a first resource is under a day for a Filament-fluent developer.
Technical risk.
Translations components. CI badges for tests, PHPStan and Rector are a genuine quality positive but validate the author's own scenarios, not ours.happenv-com is a single vendor. A Filament major release could leave us pinned and unpatched. Mitigation is a fork-and-own decision made before adoption, not after.Translations component's full method surface.required() must precede translatable(). Order-sensitive fluent chains are a code-review and onboarding tax.Key questions.
Stack fit. Laravel + Filament 4.x or 5.x with spatie/laravel-translatable already in place is the low-friction path — package v4 covers both Filament 4 and 5; Filament 3 requires the older v2 line under a different namespace, so a mixed-version estate needs two installs or an upgrade first. Astrotomic shops are supported but pay the trait-swap cost. PHP 8.2+ should be assumed and verified against the Composer constraint before committing.
Migration path. If we already store translations as Spatie JSON columns, there is no data migration — the package reads and writes the same shape. That is the single strongest argument for the Spatie route and should drive the backend decision. If we are on Astrotomic, or on hand-rolled per-locale columns, treat this as a data-shape project with its own migration plan, not a UI swap. Backend choice should be locked at the start; switching later means a full translation-table/JSON re-projection across every translatable model.
Compatibility. Two things must be version-pinned and checked in CI: the package major against the Filament major, and the translation backend against the model traits. The published asset step means the deploy pipeline needs php artisan filament:assets added alongside existing asset compilation — a small but easily-forgotten requirement that fails silently in production as broken tabs.
Sequencing.
Translations component on the same form, Astrotomic mode if applicable.required*() before translatable(), one named Translations component per form — and capture it in an internal runbook before broad rollout.Maintenance. Small dependency surface (one Composer package, one Filament plugin registration), but a live tracking obligation: every Filament major is a potential forced upgrade, and the vendor's release cadence — recent releases and CI on PHPStan/Rector — is encouraging but unproven across a major. Pin the version, watch releases, and budget roughly a day per Filament major for validation. Own a fork or a documented replacement plan; do not let a single-vendor dependency sit unexamined in the critical path of the CMS.
Support. No commercial support, no dependents, no Stack Overflow footprint. Internal ownership is mandatory: one named engineer accountable for the plugin, with the locale configuration treated as team-owned config. Escalation path is upstream issues then a local fork.
Scaling. The package is form-render only; scaling concerns are inherited from the backend. Spatie JSON columns make cross-locale search and indexing awkward at volume — plan for generated columns or a search index if content search spans locales. Forms with many locales multiply field count and per-locale required-rule evaluation; acceptable for editorial forms, worth load-testing on the widest content type. No caching or queue implications.
Failure modes.
app.fallback_locale → missing tabs or orphaned content.Translations components share a name → actions and state bleed between them.required() after translatable()) → validation silently not applied.Ramp-up. Low for anyone already fluent in Filament — the macro is discoverable and the README examples are copy-pasteable, so a first conversion is a half-day. The real ramp-up cost is in the unwritten parts: nesting behaviour, display-side handling, and the ordering rules. Budget one engineer-day for a first resource plus half a day to write the internal runbook, then treat subsequent resources as near-zero.
How can I help you explore Laravel packages today?