Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Translate Action Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

afsakar/filament-translate-action adds a translate button to Filament form fields so editors can machine-translate a value from a source locale into the other locales configured for the panel, without leaving the resource form.

Minimal setup:

  1. composer require afsakar/filament-translate-action
  2. Publish the config: php artisan vendor:publish --tag="filament-translate-action-config"
  3. Set your source locale and the list of target locales in config/filament-translate-action.php.
  4. Attach the action to a field:
use Afsakar\FilamentTranslateAction\Actions\TranslateAction;

TextInput::make('title')
    ->suffixAction(TranslateAction::make('translate'))

First real use case: a PostResource with spatie/laravel-translatable on title and body. Open the Turkish tab, write the copy, hit the translate action, and the action fills the remaining locale entries so a human can review them.

Where to look first: the published config (the locale list is the thing you will change most), the README example for the exact action-builder methods in your installed version, and composer.json for the Filament major version constraint — v1.2.x targets the Filament v3/v4 era, and mixing majors produces confusing Livewire mount errors rather than a clean composer conflict.

Implementation Patterns

One action per field, driven by shared config. Don't hardcode locales at every call site; read them from config (or a LanguageSwitcher-style helper) so the panel's locale list and the action's target list can't drift apart.

Per-locale tabs, source first. Put each locale in a Tabs component (->persistTabInQueryString()), source language as the first tab, and place the translate action on the source tab's fields. Editors translate once, then review each tab — this mirrors how translation work actually flows.

Compose a resource-level field helper. Wrap the repeated ->suffixAction(TranslateAction::make(...)) into a small static method or custom field class in your app. When you have 15 translatable fields across 6 resources, this is the difference between a one-line change and a scavenger hunt.

Translate-then-review, never translate-then-publish. Treat the output as a draft: keep the action non-destructive where possible (write only into empty target locales on edit forms), and let validation run again after the state update so length/format rules apply to machine output too.

Pair with spatie/laravel-translatable. The natural integration is a translatable model plus one JSON per attribute; the action writes into the locale keys. For plain per-locale columns (title_en, title_tr), attach the action to each column and point it at the source field explicitly.

Queue long content. For body/RichEditor fields, keep the interactive action for short fields (titles, taglines, SEO meta) and dispatch a job for long copy, then refresh the form. Inline translation of a 6k-character article will stall the Livewire round trip.

Custom provider. If Google is not acceptable (cost, compliance, quality), bind your own translator implementation in a service provider and point the config at it — keep the provider behind an interface so swapping to DeepL is a config change, not a code rewrite.

Gotchas and Tips

  • Quota and cost. The default Google path is rate-limited and either costs money or is fragile when used unauthenticated. Batch, cache by content hash, and never fire the action on afterStateUpdated for every keystroke.
  • Rich text. HTML gets mangled or its tags translated as words. Strip tags before sending for text fields, or translate text nodes individually for rich content.
  • Length limits. Requests over roughly 5k characters per call fail or get truncated. Chunk long fields and reassemble.
  • Locale codes. Google distinguishes pt and pt-BR, zh-CN and zh-TW. Filament locale keys don't always match; map them explicitly in config or you get wrong-language output that looks plausible — the worst kind of bug.
  • Don't translate identifiers. Slugs, codes, and SKUs should be regenerated from the translated title, not passed through a translator.
  • Nested forms. In repeaters, builders, and relation managers the action must resolve the correct sibling field. Verify the state path resolves as expected; a mis-scoped action silently translates the wrong field or the top-level record.
  • Config cache. php artisan config:cache after touching the locale list, or your panel and the action disagree about which locales exist.
  • Validation after fill. Translated values routinely exceed the source field's maxLength. Re-validate and surface errors on the target tabs, otherwise the form fails on save with a message pointing at a tab the editor never opened.
  • Missing UI strings. v1.2.1 only adds package-level translations. If you still see raw keys, you're on an older tag or you've overridden the package's lang files — check lang/vendor/filament-translate-action after publishing.
  • Debugging. Log the raw provider response alongside the detected source language; "it translated into the wrong language" is almost always a mis-keyed locale or a wrong detected source, not a broken package. Watch the Livewire network payload to confirm what was actually sent.
  • Extension points. Subclass the action for team-specific defaults (target locales, provider, confirmation modal) rather than repeating ->targetLanguages([...]) everywhere; bind a custom translator in a service provider for provider swaps.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource