afsakar/filament-translate-action
Filament Translate Action adds a ready-made translation action to Filament forms, letting editors translate model fields between locales via configurable drivers and manage multilingual content without leaving the admin panel.
Architecture fit. The package is a thin Filament form-action wrapper around a machine-translation provider. It slots into the admin layer, not the domain layer: it mutates form state (locale keyed values) and leaves persistence, validation, and business rules to the host application. That is the right boundary for a TPM to endorse — it means adoption does not require changes to models, schemas, or APIs, and removal is a one-line composer remove plus deleting the attached actions. If the product already runs Laravel + Filament with spatie/laravel-translatable (or per-locale columns), the fit is near-native. If the admin is Inertia/Vue, Nova, or a bespoke SPA, this package is inapplicable and the evaluation ends there.
Integration feasibility. Low-to-moderate. Installation is three commands (composer require, publish config, set source/target locales) plus a ->suffixAction(TranslateAction::make('translate')) on each translatable field. The real effort is not installation — it is the surrounding workflow: locale mapping between Filament keys and provider codes, tab-based per-locale layout, validation re-runs after machine output, and deciding where the action is allowed to write. A competent Laravel developer should reach a working demo in half a day; a production-grade rollout across many resources, with guardrails, is a one-to-three sprint piece of enablement work owned by the localization-minded engineer, not a ticket.
Technical risk. Concentrated in four places, none of them the package's own code:
pt vs pt-BR, zh-CN vs zh-TW) produce plausible-looking output in the wrong language. That is the worst failure mode for a content team because it survives human review, and it argues for explicit mapping plus a review step in the workflow, not a trust-the-button posture.maxLength. Each is a known, cheap mitigation — but only if it is planned, not discovered in UAT.Key questions for engineering.
Stack fit. Adopt if and only if the admin is Laravel + Filament and the content model is translatable. It is a natural companion to spatie/laravel-translatable: one JSON attribute per field, one action per field writing into the locale keys. For plain per-locale columns (title_en, title_tr), attach per column and point each at its source explicitly — more wiring, same result. Do not attempt to use it as a general translation service; it is an editor affordance.
Migration path. Nothing to migrate. This is additive: no schema change, no data backfill, no API surface change. That is the strongest argument for adoption — it can be trialed behind a feature flag, exercised on a single low-traffic resource, and removed cleanly. The one sequencing dependency is the translator abstraction: if the team binds a provider interface early, every later provider decision is a config change. If they do not, every provider decision becomes a refactor.
Compatibility. Three axes to pin explicitly in composer.json and the deployment notes: the Filament major (v3/v4 era is the target), the Laravel/PHP floor, and the provider SDK or HTTP client version. Treat the Filament constraint as the sharp edge — the failure mode is a Livewire mount error, which reads like an application bug and eats engineering hours. Also flag php artisan config:cache as a deployment step: if the panel's locale list and the action's target list drift because one is cached, the action translates into locales the UI does not show.
Sequencing. Recommended four-stage rollout, each a shippable increment:
TranslateAction::make(...) with team defaults (target locales, provider, confirmation modal) so no resource repeats configuration. Add the locale mapping table. Adopt the per-locale Tabs layout with the source tab first and ->persistTabInQueryString().Decision framing. This is a build-vs-buy call with a narrow, favorable answer: buy for a lightweight in-admin translate button on an existing Filament stack, build only if the workflow needs approvals, glossaries, translation memory, audit trails, or vendor SLAs — none of which this package attempts. Document that boundary in the decision record so a later request for "approval workflow" is understood as a different product, not a missing feature of this one.
Maintenance. Low, with one caveat. The package itself is small and stable; the maintenance load lives in the surrounding configuration (locale list, provider key, mapping table) and in the internal helper the team builds. The caveat is upstream velocity: one maintainer, 38 stars, last release October 2024, and a patch-level 2024-10-10 release that only added missing translations. Budget a half-day per year to evaluate currency against the Filament major, and decide up front whether the team will fork. For an admin convenience feature, "pin the version and revisit annually" is a defensible posture — but write it down rather than assuming someone is watching.
Support. No vendor. Support model is internal: one named owner (the engineer who builds the field helper), a short runbook covering the config cache step, the locale mapping table, and where the provider key lives, and a documented decision that translation quality complaints route to the localization/content owner rather than to engineering. Set that expectation early — a translate button creates an implicit promise about output quality, and stakeholders will treat machine output as a feature if nobody frames it as a draft.
Scaling. Two dimensions, with different shapes.
afterStateUpdated for every keystroke — a naive autotranslate-on-change will burn quota and degrade the form. Long copy belongs in a queued job. Chunk anything approaching the ~5k-character per-call limit.Failure modes to instrument and communicate. Ranked by what actually hurts:
pt/pt-BR and zh-CN/zh-TW pairs specifically.maxLength, form fails on a tab the editor never opened. Mitigation: re-validate after fill and surface errors on the target tab.Ramp-up. For editors: minutes. The interaction is a button that fills fields they already understand, and the per-locale tab layout mirrors how translation work already flows — write the source, translate, review each tab. The real training investment is editorial discipline, not tooling: teach translate-then-review, never translate-then-publish, and be explicit that machine output is a draft that will be edited. For engineering: half a day to working demo, one to three sprints to a guardrailed rollout across resources. For the TPM: the useful artifacts are the locale mapping table, the write-policy decision (empty targets only, or overwrite), the in-scope field list split into inline versus queued, and a one-page note on what the package deliberately does not do. That last document prevents the most likely future mistake — someone requesting approval workflows or a glossary and treating their absence as a regression rather than as scope this tool was never meant to cover.
How can I help you explore Laravel packages today?