lara-zeus/spatie-translatable
Filament v4 plugin adding Spatie Laravel Translatable support to your admin panel. Includes default locales, locale switcher, translation on create/edit/list/view pages, per-resource locale settings, and translatable relation managers.
Install the Package
composer require lara-zeus/spatie-translatable
Publish the config (if needed):
php artisan vendor:publish --provider="LaraZeus\SpatieTranslatable\SpatieTranslatableServiceProvider"
Configure Your Model
Ensure your Eloquent model uses Spatie’s HasTranslations trait:
use Spatie\Translatable\HasTranslations;
class Post extends Model
{
use HasTranslations;
public $translatable = ['title', 'content'];
}
Enable Translatable in Filament Resource
Add the HasTranslatable trait to your Filament resource:
use LaraZeus\SpatieTranslatable\Traits\HasTranslatable;
class PostResource extends Resource
{
use HasTranslatable;
// ...
}
Define Translatable Locales
Set default locales in config/spatie-translatable.php or override per resource:
public static function getTranslatableLocales(): array
{
return ['en', 'es', 'fr'];
}
First Use Case: Basic Translation
Post in Filament. The UI will automatically include a locale switcher (dropdown or tabs).title, content) for each locale. Changes are saved to the database as JSON (or separate tables if configured in Spatie’s package).config/spatie-translatable.php for global settings (e.g., default locales, JSON storage).HasTranslatable for resources and HasActiveLocaleSwitcher for locale management.HasTranslations to your model and define $translatable.HasTranslatable to your Filament resource.php artisan migrate (if using separate tables).HasTranslations trait to mark fields as translatable.
class Product extends Model
{
use HasTranslations;
public $translatable = ['name', 'description', 'meta_title'];
}
translations column (default) or separate tables (configured in Spatie’s package).product->getTranslation('es', 'name').HasTranslatable to your resource to enable locale switchers and translatable forms.
class ProductResource extends Resource
{
use HasTranslatable;
public static function getTranslatableLocales(): array
{
return ['en', 'de'];
}
}
HasActiveLocaleSwitcher).$translatable become locale-aware in create/edit forms.config/spatie-translatable.php:
'default_locale' => 'en',
'locales' => ['en', 'es', 'fr'],
getTranslatableLocales() in your resource.Post has many Comment).
class PostResource extends Resource
{
public static function getRelations(): array
{
return [
RelationManager::make('comments', CommentResource::class)
->useHasTranslatable(), // Enable translations for comments
];
}
}
Post.Filament\Forms\Components\Field and implement locale-aware logic (see Lara Zeus’ MultiLang example).text or json type:
Schema::table('products', function (Blueprint $table) {
$table->json('translations')->nullable();
});
config/translatable.php:
'storage' => 'json',
php artisan vendor:publish --provider="Spatie\Translatable\TranslatableServiceProvider" --tag="migrations"
php artisan migrate
config/translatable.php:
'storage' => 'database',
class ProductResource extends Resource
{
use HasActiveLocaleSwitcher;
public static function getActiveLocaleSwitcher(): bool
{
return false; // Disable default
}
}
getActiveLocale() and setActiveLocale() methods.public static function getTranslatableLocales(): array
{
return Locale::query()->pluck('code')->toArray();
}
HasTranslations trait and test translation retrieval:
$post = new Post();
$post->setTranslation('title', 'es', 'Título');
$this->assertEquals('Título', $post->getTranslation('es', 'title'));
$this->actingAs($user)
->get('/admin/resources/posts')
->assertSee('en'); // Check locale switcher
filament-spatie-media-library).mvenghaus/translatable-inline:
public static function getActiveLocaleSwitcher(): bool
{
return false;
}
meta-title) must be double-quoted in the database.null instead of falling back to the default locale.public function getTranslatedAttribute($locale)
{
return $this->getTranslation($locale, 'title') ?? $this->getTranslation(config('translatable.default_locale'), 'title');
}
->refresh():
$resource->getRelationManager('comments')->refresh();
translations columnHow can I help you explore Laravel packages today?