| Install | |
|---|---|
composer require jeffersongoncalves/filament-translatable |
|
| Latest Version: | v3.0.1 |
| PHP: | ^8.2 |

Enhanced Filament plugin for spatie/laravel-translatable with translation status indicators, locale flags, and improved developer experience.
| Branch | Filament | PHP | Laravel | Tailwind | Livewire | Install |
|---|---|---|---|---|---|---|
| 1.x | v3 | ^8.1 | 10+ | 3.x | 3.x | "^1.0" |
| 2.x | v4 | ^8.2 | 11+ | 4.x | 3.x | "^2.0" |
| 3.x | v5 | ^8.2 | 11.28+ | 4.x | 4.x | "^3.0" |
You are viewing the documentation for branch 3.x (Filament v5).
InteractsWithTranslations for less boilerplateYou can install the package via composer:
composer require jeffersongoncalves/filament-translatable:"^3.0"
Optionally publish the config:
php artisan vendor:publish --tag="filament-translatable-config"
Your model must use Spatie's HasTranslations trait:
use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class Post extends Model
{
use HasTranslations;
protected $fillable = ['title', 'content', 'slug'];
public array $translatable = ['title', 'content'];
}
Translatable columns must use json type in your migration:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->json('title');
$table->json('content');
$table->string('slug'); // non-translatable fields use regular column types
$table->timestamps();
});
Add the plugin to your PanelProvider:
use JeffersonGoncalves\FilamentTranslatable\FilamentTranslatablePlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
FilamentTranslatablePlugin::make()
->defaultLocales(['en', 'pt_BR', 'es']),
]);
}
use JeffersonGoncalves\FilamentTranslatable\Resources\Concerns\Translatable;
class PostResource extends Resource
{
use Translatable;
// ...
}
Each page type needs its own trait and the LocaleSwitcher header action:
use JeffersonGoncalves\FilamentTranslatable\Actions\LocaleSwitcher;
use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\CreateRecord;
use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\EditRecord;
use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\ListRecords;
class CreatePost extends CreateRecord
{
use CreateRecord\Concerns\Translatable;
protected function getHeaderActions(): array
{
return [LocaleSwitcher::make()];
}
}
class EditPost extends EditRecord
{
use EditRecord\Concerns\Translatable;
protected function getHeaderActions(): array
{
return [LocaleSwitcher::make()];
}
}
class ListPosts extends ListRecords
{
use ListRecords\Concerns\Translatable;
protected function getHeaderActions(): array
{
return [LocaleSwitcher::make()];
}
}
Additional page types are also supported:
use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\ViewRecord;
use JeffersonGoncalves\FilamentTranslatable\Resources\Pages\ManageRecords;
// ViewRecord
class ViewPost extends ViewRecord
{
use ViewRecord\Concerns\Translatable;
protected function getHeaderActions(): array
{
return [LocaleSwitcher::make()];
}
}
// ManageRecords (simple resource)
class ManagePosts extends ManageRecords
{
use ManageRecords\Concerns\Translatable;
protected function getHeaderActions(): array
{
return [LocaleSwitcher::make()];
}
}
Show translation completeness per locale in your table with colored badges:
use JeffersonGoncalves\FilamentTranslatable\Tables\Columns\TranslationStatusColumn;
public static function table(Table $table): Table
{
return $table->columns([
TextColumn::make('title'),
TranslationStatusColumn::make('translations')
->showPercentage() // show completion percentage
->onlyShowMissing() // hide locales that are fully translated
->showFlags() // show emoji flags next to locale labels
->locales(['en', 'pt_BR', 'es']), // override plugin locales
]);
}
Each locale displays a colored badge indicating its translation status:
Use HasTranslationStatus on any page to check translation status programmatically:
use JeffersonGoncalves\FilamentTranslatable\Concerns\HasTranslationStatus;
class EditPost extends EditRecord
{
use EditRecord\Concerns\Translatable;
use HasTranslationStatus;
}
Available methods:
// Get status per locale: 'complete', 'partial', or 'empty'
$this->getTranslationStatus($record);
// => ['en' => 'complete', 'pt_BR' => 'partial', 'fr' => 'empty']
// Get completeness percentage per locale (0-100)
$this->getTranslationCompleteness($record);
// => ['en' => 100, 'pt_BR' => 50, 'fr' => 0]
// Get locales that have at least one translated attribute
$this->getTranslatedLocales($record);
// => ['en', 'pt_BR']
The plugin ships with 30+ built-in emoji flags. Configure them per locale in the plugin or via config:
FilamentTranslatablePlugin::make()
->defaultLocales(['en', 'pt_BR', 'es'])
->localeFlags([
'en' => "\u{1F1FA}\u{1F1F8}",
'pt_BR' => "\u{1F1E7}\u{1F1F7}",
'es' => "\u{1F1EA}\u{1F1F8}",
])
->flagDisplay('flag_and_label'), // 'flag_and_label' | 'flag_only' | 'label_only'
Built-in flags include: en, pt_BR, pt, es, fr, de, it, nl, ja, ko, zh, ru, ar, hi, tr, pl, uk, sv, da, no, fi, cs, el, ro, hu, th, vi, id, ms, he.
Override how locale names are displayed:
FilamentTranslatablePlugin::make()
->defaultLocales(['en', 'pt_BR'])
->getLocaleLabelUsing(fn (string $locale) => match ($locale) {
'en' => 'English',
'pt_BR' => 'Portugues',
default => null, // falls back to locale_get_display_name()
}),
Relation managers have independent locale management using a dedicated LocaleSwitcher:
use JeffersonGoncalves\FilamentTranslatable\Resources\RelationManagers\Concerns\Translatable;
use JeffersonGoncalves\FilamentTranslatable\Tables\Actions\LocaleSwitcher;
class CommentsRelationManager extends RelationManager
{
use Translatable;
protected function getHeaderActions(): array
{
return [LocaleSwitcher::make()];
}
}
Note: Relation managers use
JeffersonGoncalves\FilamentTranslatable\Tables\Actions\LocaleSwitcher(fromTables\Actions), while pages useJeffersonGoncalves\FilamentTranslatable\Actions\LocaleSwitcher(fromActions).
For less boilerplate, you can use the unified InteractsWithTranslations trait instead of page-specific traits:
use JeffersonGoncalves\FilamentTranslatable\Concerns\InteractsWithTranslations;
class EditPost extends EditRecord
{
use InteractsWithTranslations;
// Automatically detects the page type and provides
// getTranslatableLocales() and locale management
}
// config/filament-translatable.php
return [
/*
|--------------------------------------------------------------------------
| Locale Flags
|--------------------------------------------------------------------------
|
| Map of locale codes to emoji flags. Used by the LocaleSwitcher and
| TranslationStatusColumn to display visual locale indicators.
|
*/
'locale_flags' => [
'en' => "\u{1F1FA}\u{1F1F8}", // US
'pt_BR' => "\u{1F1E7}\u{1F1F7}", // BR
'es' => "\u{1F1EA}\u{1F1F8}", // ES
'fr' => "\u{1F1EB}\u{1F1F7}", // FR
'de' => "\u{1F1E9}\u{1F1EA}", // DE
// ... 25+ more built-in
],
/*
|--------------------------------------------------------------------------
| Flag Display Format
|--------------------------------------------------------------------------
|
| Controls how locale labels are displayed in the LocaleSwitcher.
| Options: 'flag_and_label', 'flag_only', 'label_only'
|
*/
'flag_display' => 'flag_and_label',
/*
|--------------------------------------------------------------------------
| Translation Status Colors
|--------------------------------------------------------------------------
|
| Filament color names used by the TranslationStatusColumn badges.
|
*/
'status_colors' => [
'complete' => 'success',
'partial' => 'warning',
'empty' => 'danger',
],
];
filament/spatie-laravel-translatable-pluginThis package is an enhanced fork of Filament's official translatable plugin. Migration is straightforward:
1. Replace the package:
composer remove filament/spatie-laravel-translatable-plugin
composer require jeffersongoncalves/filament-translatable:"^3.0"
2. Update PanelProvider imports:
// Before
use Filament\SpatieLaravelTranslatablePlugin;
// After
use JeffersonGoncalves\FilamentTranslatable\FilamentTranslatablePlugin;
3. Update Resource and Page imports:
Replace Filament\Resources\ with JeffersonGoncalves\FilamentTranslatable\Resources\ in all translatable traits.
4. Update LocaleSwitcher imports:
// Before
use Filament\Actions\LocaleSwitcher;
// After (for pages)
use JeffersonGoncalves\FilamentTranslatable\Actions\LocaleSwitcher;
// After (for relation managers)
use JeffersonGoncalves\FilamentTranslatable\Tables\Actions\LocaleSwitcher;
5. Enjoy the new features - Translation Status Column, locale flags, and status introspection are ready to use.
composer test
Please see Releases for more information on what has changed recently.
The MIT License (MIT). Please see License File for more information.