Skip to main content
Back to packages
2,444 GitHub stars

spatie/laravel-translatable

View on GitHub

Description

This package contains a trait to make Eloquent models translatable. Translations are stored as json. There is no extra table needed to hold them.

This package contains a trait HasTranslations to make Eloquent models translatable. Translations are stored as json. There is no extra table needed to hold them.

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\Attributes\Translatable;
use Spatie\Translatable\HasTranslations;
 
#[Translatable('name', 'description')]
class NewsItem extends Model
{
use HasTranslations;
 
// ...
}

The attribute accepts a variadic list of column names, so you can pass as many as you need.

Alternatively, you can declare the translatable attributes via a public $translatable property:

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
 
class NewsItem extends Model
{
use HasTranslations;
 
public $translatable = ['name'];
}

When both the property and the attribute are present, their values are merged and deduplicated.

After the trait is applied on the model you can do these things:

$newsItem = new NewsItem;
$newsItem
->setTranslation('name', 'en', 'Name in English')
->setTranslation('name', 'nl', 'Naam in het Nederlands')
->save();
 
$newsItem->name; // Returns 'Name in English' given that the current app locale is 'en'
$newsItem->getTranslation('name', 'nl'); // returns 'Naam in het Nederlands'
 
app()->setLocale('nl');
$newsItem->name; // Returns 'Naam in het Nederlands'
 
$newsItem->getTranslations('name'); // returns an array of all name translations
 
// You can translate nested keys of a JSON column using the -> notation
// First, add the path to the $translatable array, e.g., 'meta->description'
$newsItem
->setTranslation('meta->description', 'en', 'Description in English')
->setTranslation('meta->description', 'nl', 'Beschrijving in het Nederlands')
->save();
 
$attributeKey = 'meta->description';
$newsItem->$attributeKey; // Returns 'Description in English'
$newsItem->getTranslation('meta->description', 'nl'); // Returns 'Beschrijving in het Nederlands'

Also providing scoped queries for retrieving records based on locales

// Returns all news items with a name in English
NewsItem::whereLocale('name', 'en')->get();
 
// Returns all news items with a name in English or Dutch
NewsItem::whereLocales('name', ['en', 'nl'])->get();
 
// Returns all news items that has name in English with value `Name in English`
NewsItem::query()->whereJsonContainsLocale('name', 'en', 'Name in English')->get();
 
// Returns all news items that has name in English or Dutch with value `Name in English`
NewsItem::query()->whereJsonContainsLocales('name', ['en', 'nl'], 'Name in English')->get();
 
// The last argument is the "operand" which you can tweak to achieve something like this:
 
// Returns all news items that has name in English with value like `Name in...`
NewsItem::query()->whereJsonContainsLocale('name', 'en', 'Name in%', 'like')->get();
 
// Returns all news items that has name in English or Dutch with value like `Name in...`
NewsItem::query()->whereJsonContainsLocales('name', ['en', 'nl'], 'Name in%', 'like')->get();

Related Content on Laravel Daily

Video

Recent Courses on Laravel Daily

Laravel 13 Starter Kit Teams and Customizations

10 lessons
33 min

How to Build Laravel 13 API From Scratch

30 lessons
1 h 23 min

How to Structure Laravel 13 Projects

16 lessons
1 h 32 min read

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.