Weave Code
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

Spatie Translatable Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup Steps

  1. Install the Package

    composer require lara-zeus/spatie-translatable
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="LaraZeus\SpatieTranslatable\SpatieTranslatableServiceProvider"
    
  2. 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'];
    }
    
  3. Enable Translatable in Filament Resource Add the HasTranslatable trait to your Filament resource:

    use LaraZeus\SpatieTranslatable\Traits\HasTranslatable;
    
    class PostResource extends Resource
    {
        use HasTranslatable;
    
        // ...
    }
    
  4. Define Translatable Locales Set default locales in config/spatie-translatable.php or override per resource:

    public static function getTranslatableLocales(): array
    {
        return ['en', 'es', 'fr'];
    }
    
  5. First Use Case: Basic Translation

    • Create/edit a Post in Filament. The UI will automatically include a locale switcher (dropdown or tabs).
    • Translate fields (title, content) for each locale. Changes are saved to the database as JSON (or separate tables if configured in Spatie’s package).

Where to Look First

  • Official Documentation: Covers installation, configuration, and advanced features like relation managers.
  • Example Resources: Check the GitHub repo for sample implementations.
  • Config File: config/spatie-translatable.php for global settings (e.g., default locales, JSON storage).
  • Traits: Focus on HasTranslatable for resources and HasActiveLocaleSwitcher for locale management.

Quick Win: Translatable Fields in 5 Minutes

  1. Add HasTranslations to your model and define $translatable.
  2. Add HasTranslatable to your Filament resource.
  3. Run php artisan migrate (if using separate tables).
  4. Visit the Filament resource page—locale switchers and translatable fields appear automatically.

Implementation Patterns

Core Workflows

1. Model-Level Translations

  • Pattern: Use Spatie’s HasTranslations trait to mark fields as translatable.
    class Product extends Model
    {
        use HasTranslations;
    
        public $translatable = ['name', 'description', 'meta_title'];
    }
    
  • Database: Translations are stored as JSON in a translations column (default) or separate tables (configured in Spatie’s package).
  • Retrieval: Access translations via product->getTranslation('es', 'name').

2. Filament Resource Integration

  • Pattern: Add 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'];
        }
    }
    
  • UI Components: The package adds:
    • Locale Switcher: Dropdown or tabs in the top-right of Filament pages (configurable via HasActiveLocaleSwitcher).
    • Translatable Fields: Fields marked in $translatable become locale-aware in create/edit forms.

3. Locale Management

  • Global Defaults: Set in config/spatie-translatable.php:
    'default_locale' => 'en',
    'locales' => ['en', 'es', 'fr'],
    
  • Per-Resource Overrides: Use getTranslatableLocales() in your resource.
  • Session-Based Persistence: Locales persist across requests via session (enabled by default).

4. Relation Managers

  • Pattern: Enable translations for nested resources (e.g., Post has many Comment).
    class PostResource extends Resource
    {
        public static function getRelations(): array
        {
            return [
                RelationManager::make('comments', CommentResource::class)
                    ->useHasTranslatable(), // Enable translations for comments
            ];
        }
    }
    
  • Use Case: Translate comments for multilingual posts without duplicating the entire Post.

5. Custom Field Types


Integration Tips

1. With Spatie’s JSON Storage

  • Ensure your database column for translations is text or json type:
    Schema::table('products', function (Blueprint $table) {
        $table->json('translations')->nullable();
    });
    
  • Configure Spatie’s package in config/translatable.php:
    'storage' => 'json',
    

2. With Separate Tables

  • Run Spatie’s migration:
    php artisan vendor:publish --provider="Spatie\Translatable\TranslatableServiceProvider" --tag="migrations"
    php artisan migrate
    
  • Configure in config/translatable.php:
    'storage' => 'database',
    

3. Locale Switcher Customization

  • Disable the default switcher and use custom components:
    class ProductResource extends Resource
    {
        use HasActiveLocaleSwitcher;
    
        public static function getActiveLocaleSwitcher(): bool
        {
            return false; // Disable default
        }
    }
    
  • Add your own switcher using the getActiveLocale() and setActiveLocale() methods.

4. Dynamic Locales

  • Fetch locales from a database table or API:
    public static function getTranslatableLocales(): array
    {
        return Locale::query()->pluck('code')->toArray();
    }
    

5. Testing

  • Unit Tests: Mock the HasTranslations trait and test translation retrieval:
    $post = new Post();
    $post->setTranslation('title', 'es', 'Título');
    $this->assertEquals('Título', $post->getTranslation('es', 'title'));
    
  • Feature Tests: Test Filament pages with different locales:
    $this->actingAs($user)
         ->get('/admin/resources/posts')
         ->assertSee('en'); // Check locale switcher
    

Gotchas and Tips

Pitfalls

1. Locale Switcher Conflicts

  • Issue: The default locale switcher may not work with complex field types (e.g., filament-spatie-media-library).
  • Fix: Disable the switcher and use a dedicated plugin like mvenghaus/translatable-inline:
    public static function getActiveLocaleSwitcher(): bool
    {
        return false;
    }
    

2. JSON Key Validation

  • Issue: JSON keys with hyphens (e.g., meta-title) must be double-quoted in the database.
  • Fix: Ensure your database column uses proper JSON encoding or switch to separate tables.

3. Default Locale Fallback

  • Issue: If a translation is missing for the active locale, the package may return null instead of falling back to the default locale.
  • Fix: Implement custom logic in your resource:
    public function getTranslatedAttribute($locale)
    {
        return $this->getTranslation($locale, 'title') ?? $this->getTranslation(config('translatable.default_locale'), 'title');
    }
    

4. Relation Manager Caching

  • Issue: Translatable relation managers may not reflect changes immediately due to Filament’s caching.
  • Fix: Clear the relation manager cache or use ->refresh():
    $resource->getRelationManager('comments')->refresh();
    

5. Migration Conflicts

  • Issue: Running migrations after installing the package may fail if the translations column
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony