tomatophp/filament-translation-component
Filament Translation Component for Laravel: a key/value translation field for Filament forms, designed to work with Spatie Translatable. Provides input and textarea variants, light/dark styling, and configurable language support for translatable attributes.
Installation
composer require tomatophp/filament-translation-component
Publish the package assets (if needed):
php artisan vendor:publish --provider="TomatoPHP\FilamentTranslationComponent\FilamentTranslationComponentServiceProvider" --tag="filament-translation-component:views"
Prerequisites Ensure you have:
Basic Setup Add the component to a Filament resource’s form/tables using:
use TomatoPHP\FilamentTranslationComponent\Components\TranslationField;
TranslationField::make('name')
->translatable()
->languages(['en', 'fr', 'es'])
->required();
First Use Case
Display a translatable field in a Filament form for a model with Spatie’s HasTranslations trait:
use Spatie\Translatable\HasTranslations;
class Post extends Model implements HasTranslations
{
public $translatable = ['title', 'content'];
}
Form Integration
Use TranslationField in Filament forms to edit translations:
Form::components([
TranslationField::make('title')
->languages(config('app.locales'))
->columns(2), // Adjust layout
]);
Table Display Show translations in Filament tables with:
Tables\Columns\TranslationColumn::make('title')
->languages(['en', 'fr'])
->sortable();
Dynamic Languages Fetch languages from config or a database:
TranslationField::make('description')
->languages(config('app.available_locales'))
->defaultLanguage(auth()->user()->locale);
Validation Add validation rules per language:
TranslationField::make('slug')
->rules([
'en' => 'required|unique:posts,slug',
'fr' => 'required|unique:posts,slug',
]);
Nested Resources For deeply nested translatable models, use:
TranslationField::make('nested.field')
->translatablePath('nested') // Custom path for nested attributes
->languages(['en', 'de']);
State Updates (v4.0.1 Fix) Ensure state updates for inputs work correctly by explicitly binding the field:
TranslationField::make('content')
->languages(['en', 'fr'])
->bindToModel(); // Explicitly bind to model to avoid state update issues
afterSave to sync translations to a json column if needed:
$record->saveTranslations();
TranslationField::make('bio')
->fallbackLanguage('en');
resources/views/vendor/filament-translation-component/.translate() helper to format responses:
return $post->translate(['title', 'content']);
Model Trait Conflict
Ensure your model uses HasTranslations and not Translatable (deprecated in Spatie v3+).
Fix: Update to:
use Spatie\Translatable\HasTranslations;
Language Mismatch If translations don’t save, verify:
languages() array matches your app.locales config.$translatable array includes the field name.State Update Issues (v4.0.1)
If inputs in TranslationField don’t update the state correctly, ensure:
bindToModel().CSRF Token Issues When using the component in modals or AJAX forms, ensure CSRF protection is configured:
TranslationField::make('content')->deferCsrf();
Performance with Large Data Avoid loading all translations at once. Use lazy loading:
TranslationField::make('content')->lazyLoad();
Filament Version Lock The package may not support Filament v2. Check the release notes for compatibility.
dd($record->getTranslations('title'));
FILAMENT_DEBUG=true
php artisan view:clear
TranslationField::make('field')->bindToModel()->debug(); // Use debug mode if available
Custom Translatable Attributes Extend the component to support non-Spatie translatable models:
TranslationField::make('custom_field')
->customTranslator(fn ($model, $attribute, $locale) => $model->{"get{$attribute}Translation"}($locale));
Add Language Switcher
Use Filament’s Action to toggle languages dynamically:
Action::make('switchLanguage')
->label('Switch to French')
->action(fn () => session()->put('locale', 'fr'));
Hook into Translation Events Listen for translation updates via Spatie’s events:
\Spatie\Translatable\Events\TranslationSaved::dispatch($model, $attribute, $locale);
Override Default Behavior Publish and modify the component’s logic:
php artisan vendor:publish --tag="filament-translation-component"
Then edit app/Providers/FilamentTranslationComponentServiceProvider.php.
filament-spatie-translatable for tighter integration.Panel::make()->defaultLocale('fr');
$this->filament()->actingAs($user)
->fillForm([
'title' => [
'en' => 'Hello',
'fr' => 'Bonjour',
],
]);
TranslationField::make('dynamic_field')->bindToModel();
How can I help you explore Laravel packages today?