Handling missing translations | laravel-translatable | Spatie

 SPATIE

  Laravel Translatable
=======================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-translatable](https://spatie.be/docs/laravel-translatable/v6)  Basic-usage  Handling missing translations

 Version   v6

 Other versions for crawler [v6](https://spatie.be/docs/laravel-translatable/v6)

- [ Introduction ](https://spatie.be/docs/laravel-translatable/v6/introduction)
- [ Support us ](https://spatie.be/docs/laravel-translatable/v6/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-translatable/v6/requirements)
- [ Upgrading ](https://spatie.be/docs/laravel-translatable/v6/upgrading)
- [ Installation &amp; setup ](https://spatie.be/docs/laravel-translatable/v6/installation-setup)
- [ Questions and issues ](https://spatie.be/docs/laravel-translatable/v6/questions-issues)
- [ Changelog ](https://spatie.be/docs/laravel-translatable/v6/changelog)
- [ About us ](https://spatie.be/docs/laravel-translatable/v6/about-us)

Basic usage
-----------

- [ Getting and setting translations ](https://spatie.be/docs/laravel-translatable/v6/basic-usage/getting-and-settings-translations)
- [ Removing translations ](https://spatie.be/docs/laravel-translatable/v6/basic-usage/removing-translations)
- [ Replacing translations ](https://spatie.be/docs/laravel-translatable/v6/basic-usage/replacing-translations)
- [ Querying translations ](https://spatie.be/docs/laravel-translatable/v6/basic-usage/querying-translations)
- [ Validation translations ](https://spatie.be/docs/laravel-translatable/v6/basic-usage/validating-translations)
- [ Handling missing translations ](https://spatie.be/docs/laravel-translatable/v6/basic-usage/handling-missing-translations)

Advanced usage
--------------

- [ Available events ](https://spatie.be/docs/laravel-translatable/v6/advanced-usage/available-events)
- [ Customize the toArray method ](https://spatie.be/docs/laravel-translatable/v6/advanced-usage/customize-the-toarray-method)
- [ Usage with factories ](https://spatie.be/docs/laravel-translatable/v6/advanced-usage/usage-with-factories)

 Handling missing translations
=============================

Sometimes your model doesn't have a requested translation. Using the fallback functionality, you can decide what should happen.

To set up fallback you need to call static method on the facade `Spatie\Translatable\Facades\Translatable`. Typically, you would put this in [a service provider of your own](https://laravel.com/docs/8.x/providers#writing-service-providers):

```
    // typically, in a service provider

    use Spatie\Translatable\Facades\Translatable;

    Translatable::fallback(
        ...
    );
```

### Falling back to a specific locale

If you want to have another `fallback_locale` than the app fallback locale (see `config/app.php`), you should pass it as `$fallbackLocale` parameter:

```
    use Spatie\Translatable\Facades\Translatable;

    Translatable::fallback(
        fallbackLocale: 'fr',
    );
```

### Fallback locale per model

If the fallback locale differs between models, you can define a `getFallbackLocale()` method on your model.

```
use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;

class NewsItem extends Model
{
    use HasTranslations;

    public $fillable = ['name', 'fallback_locale'];

    public $translatable = ['name'];

    public function getFallbackLocale() : string
    {
        return $this->fallback_locale;
    }
}
```

### Falling back to any locale

Sometimes it is favored to return any translation if neither the translation for the preferred locale nor the fallback locale are set. To do so, just pass `$fallbackAny` to true:

```
    use Spatie\Translatable\Facades\Translatable;

    Translatable::fallback(
         fallbackAny: true,
    );
```

### Customize fallbacks

You can set up a fallback callback that is called when a translation key is missing/not found. It just lets you execute some custom code like logging something or contact a remote service for example.

You have to register some code you want to run, by passing a closure to `$missingKeyCallback`.

Here's an example with a closure that logs a warning with some info about the missing translation key:

```
use Spatie\Translatable\Facades\Translatable;
use Illuminate\Support\Facades\Log;

Translatable::fallback(missingKeyCallback: function (
   Model $model,
   string $translationKey,
   string $locale,
   string $fallbackTranslation,
   string $fallbackLocale,
) {

    // do something (ex: logging, alerting, etc)

    Log::warning('Some translation key is missing from an eloquent model', [
       'key' => $translationKey,
       'locale' => $locale,
       'fallback_locale' => $fallbackLocale,
       'fallback_translation' => $fallbackTranslation,
       'model_id' => $model->id,
       'model_class' => get_class($model),
    ]);
});
```

If the closure returns a string, it will be used as the fallback translation:

```
use Spatie\Translatable\Facades\Translatable;
use App\Service\MyRemoteTranslationService;

Translatable::fallback(missingKeyCallback: function (
    Model $model,
    string $translationKey,
    string $locale,
    string $fallbackTranslation,
    string $fallbackLocale
    ) {

    return MyRemoteTranslationService::getAutomaticTranslation($fallbackTranslation, $fallbackLocale, $locale);
});
```

### Disabling fallbacks on a per model basis

By default, a fallback will be used when you access a non-existent translation attribute.

You can disable fallbacks on a model with the `$useFallbackLocale` property.

```
use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;

class NewsItem extends Model
{
    use HasTranslations;

    public $translatable = ['name'];

    protected $useFallbackLocale = false;
}
```
