To install and configure Spatie for translations in a Laravel project, follow these detailed steps:
1. Install the Package
Run the composer command to require the Spatie Laravel Translatable package:
bash
composer require spatie/laravel-translatable
This installs the package and it will automatically register its service provider[1][4].
2. Prepare Your Database
Ensure the database column(s) you want to translate are of type `json`. If your database does not support JSON columns, use `text` as the column type instead. This is important because the package stores translations as JSON objects in a single column[1][4].
You can create or modify a migration like this:
php
Schema::table('news_items', function (Blueprint $table) {
$table->json('name')->nullable();
});
Or use `text('name')->nullable()` if JSON is unsupported.
3. Make Your Model Translatable
In the Eloquent model where you want translations, do the following:
- Import and use the `Spatie\Translatable\HasTranslations` trait.
- Define a public property `$translatable` as an array listing the attributes you want to be translatable.
Example:
php
use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class NewsItem extends Model
{
use HasTranslations;
public array $translatable = ['name'];
}
This setup tells the package which attributes to handle as translatable JSON fields[1][3][4].
4. Using the Package
- To set a translation for the current locale, simply assign a string to the translatable attribute:
php
$newsItem->name = 'Hello World'; // sets for current locale
- To set translations for multiple locales, assign an array:
php
$newsItem->setTranslations('name', [
'en' => 'Hello World',
'fr' => 'Bonjour le monde',
]);
- To get the translation for the current locale:
php
echo $newsItem->name;
- To get a translation for a specific locale:
php
echo $newsItem->getTranslation('name', 'fr');
This makes it easy to manage translations directly on the model attributes[2].
5. Important Notes
- Always query translatable attributes through Eloquent models, not raw database queries, to get translated values properly. Raw queries will return the JSON string from the database[5].
- If you want to store translations in the database for Laravel's usual translation system (not model attributes), Spatie offers a separate package `laravel-translation-loader` that manages translation lines stored in a database table. This involves replacing Laravel's translation service provider and running migrations for a `language_lines` table[6][8].
In summary, the core steps are: install via composer, prepare your database columns as JSON, add the HasTranslations trait and $translatable property to your model, then use the model attributes to get/set translations seamlessly. This approach stores all translations for an attribute in a single JSON column, simplifying multi-language content management[1][4].
Citations:
[1] https://spatie.be/docs/laravel-translatable/v6/installation-setup
[2] https://spatie.be/docs/laravel-translatable/v6/basic-usage/getting-and-settings-translations
[3] https://github.com/spatie/laravel-translatable/blob/main/docs/installation-setup.md
[4] https://laraveldaily.com/lesson/multi-language-laravel/spatie-laravel-translatable
[5] https://stackoverflow.com/questions/61974537/laravel-spatie-translation-package-not-working-for-raw-queries-and-join-operatio
[6] https://github.com/spatie/laravel-translation-loader
[7] https://www.youtube.com/watch?v=rXIpPaF5evc
[8] https://packagist.org/packages/spatie/laravel-translation-loader
[9] https://spatie.be/docs/laravel-backup/v9/installation-and-setup