Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

spatie/laravel-translatable

Premium
9 min read

Instead of creating multiple tables and handling translations via a different table, this package uses a single table and a JSON column to store the translations.


Installation

Installation guide for this package is really simple and consists only of two steps:

Require the package via composer:

composer require spatie/laravel-translatable

And for the models you want to translate add the Spatie\Translatable\HasTranslations trait with $translatable property:

Model

use Spatie\Translatable\HasTranslations;
 
class Post extends Model
{
use HasTranslations;
 
public $translatable = ['title'];
}

That is it! Now if you set up the database column title to be a JSON column (or TEXT in unsupported databases), you can start using the package.


Usage

Here's a quick example of how we used this package:...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

AH
Ahmed Habeeb ✓ Link copied!

I want add thing if want add more than languages so you need add tab like this ex: @foreach (config('locales.languages') as $key => $val)

  • {{$val['name']}}
  • @endforeach

    </ul>
    
    @foreach (config('locales.languages') as $key => $val)

    Meta-Bereich

    ** and if want add auto transtion with deepl **
    				<?php
    

    namespace App\Translators;

    use GuzzleHttp\Client; use Illuminate\Support\Facades\Cache;

    class DeepLTranslator { public function translate($text, $target_lang = 'de') { // dd($text); if (\is_array($text)){ $text = $text['de']; } // Check if the translation is already in the cache $cachedTranslation = Cache::get("translation_{$text}_{$target_lang}"); if ($cachedTranslation) { return $cachedTranslation; }

        $client = new Client();
    

    try{ $response = $client->post('https://api.deepl.com/v2/translate', [ 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'name' ], 'form_params' => [ 'auth_key' => env('DEEPL_API_KEY'), 'text' => $text, 'target_lang' => $target_lang ] ]); } catch (\Exception $e) { return $e->getMessage(); }

        $result = json_decode($response->getBody()->getContents());
        // Store the translation in the cache
        Cache::put("translation_{$text}_{$target_lang}", $result->translations[0]->text, 1440);
        return $result->translations[0]->text;
    }
    

    }

    IM
    Ismail Mahmoud ✓ Link copied!

    in index blade nothing is shows when applying the package

    M
    Modestas ✓ Link copied!

    can you explain what the issue is a bit more?

    IM
    Ismail Mahmoud ✓ Link copied!

    im trying to use spatie/laravel-translatable to translate model called ProductCategory, in create and edit forms worked fine, but when i tried to display the traslated fileds according to the current local it not showin anything at all. hit: im using quick admin panel generator, so the default generated code for locale inside config/panel.php not in config/app.php so that is the only bit of code i have changed in the above lesson

    M
    Modestas ✓ Link copied!

    Have you added:

     public $translatable = ['title', 'post'];
    

    To your models?

    If yes, I would just dump what the models returns or what the database contains.

    IM
    Ismail Mahmoud ✓ Link copied!

    Model ProductCategory:

    use Spatie\Translatable\HasTranslations;

    class ProductCategory extends Model implements HasMedia { use SoftDeletes, InteractsWithMedia, Auditable, HasFactory, HasTranslations;

    public $translatable = ['name','description'];
    
    IM
    Ismail Mahmoud ✓ Link copied!

    #attributes: array:6 [▼ "id" => 1 "name" => "{"English":"Oil","Arabic":"\u0632\u064a\u0648\u062a"}" "description" => "{"English":"Officiis qui enim al","Arabic":"\u0632\u064a\u0648\u062a"}" "created_at" => "2023-05-28 07:38:31" "updated_at" => "2023-05-28 07:38:31" "deleted_at" => null

    M
    Modestas ✓ Link copied!

    It seems that the package works, yet I'm a little bit confused why it has full language names as it should be en or ar instead of full names. So please check how you are saving the data :)

    IM
    Ismail Mahmoud ✓ Link copied!

    Fixed it, and here was the problem this is panel.php content return [ 'date_format' => 'Y-m-d', 'time_format' => 'H:i:s', 'primary_language' => 'en', 'available_languages' => [ 'en' => 'English', 'ar' => 'Arabic', ], 'registration_default_role' => '2',

    ];

    i was saveing the value of the locale instead of key @foreach(config('panel.available_languages')) as $locale the correct is: @foreach(config('panel.available_languages')) as $key => $value then use the key instead of using the value.

    Thanks a lot of quick responding

    Great Team