---
title: "The Translatable facade — Translatable for Laravel | Roundly"
description: "Every locale-map helper on one facade — supported locales, locale checks, fallback resolution, admin input, rules, search and usingLocale()."
url: https://roundly-consulting.com/open-source/docs/translatable-for-laravel/facade
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Translatable for Laravel](https://roundly-consulting.com/open-source/docs/translatable-for-laravel.md)

# The Translatable facade

Everything that isn’t per-model state lives on the Translatable facade, over the injectable TranslationManager singleton. The HasTranslations trait reads its locale set, fallback settings, locale-key validation and map resolution through the same manager, so the facade and your models always agree:

```php
use RoundlyConsulting\Translatable\DataTransferObjects\TranslationChanges;
use RoundlyConsulting\Translatable\DataTransferObjects\TranslationSearch;
use RoundlyConsulting\Translatable\Enums\FallbackMode;
use RoundlyConsulting\Translatable\Facades\Translatable;

// Locales
Translatable::supported();                        // ['en', 'sk'] — from the bound SupportedLocales
Translatable::isSupported('sk');                  // true — exact, case-sensitive
Translatable::currentLocale();                    // app()->getLocale()
Translatable::ensureLocale($locale);              // returns it, or throws InvalidLocaleException (malformed)
Translatable::ensureLocale($locale, strict: true); // … also throws when it is not supported

// Fallback chain
Translatable::fallbackMode();                     // FallbackMode, from config
Translatable::fallbackLocale();                   // 'en'
Translatable::resolve(['en' => 'Investing', 'sk' => 'Investovanie']);        // current locale + configured fallback
Translatable::resolve($map, 'de', FallbackMode::Fallback, fallbackLocale: 'sk');

// Admin input
Translatable::fromInput($request->input('name')); // clean locale map
Translatable::rules('name', required: true, each: ['max:120']);
Translatable::filledRule('name');                 // just the "at least one locale" rule
Translatable::apply($topic, TranslationChanges::make(['name' => ['sk' => 'Sporenie']])); // merge in memory, then save()

// Queries and locale scoping
Translatable::search(Topic::query(), new TranslationSearch(fields: ['name'], term: 'invest'));
Translatable::usingLocale('sk', fn (): string => $topic->name);
```

The facade (RoundlyConsulting\\Translatable\\Facades\\Translatable) shares its short name with the model contract (RoundlyConsulting\\Translatable\\Contracts\\Translatable) — alias one of them in a file that needs both. Per-model reads, writes, status and scopes stay on the model itself (see Reading and writing).

## Method reference

| Method | Returns | Purpose |
| --- | --- | --- |
| `supported()` | list<string> | Supported locales, from the bound SupportedLocales. |
| `isSupported($locale)` | bool | Exact, case-sensitive membership in supported(). |
| `currentLocale()` | string | The app locale — app()->getLocale(). |
| `ensureLocale($locale, $strict = false)` | string | Returns the key or throws InvalidLocaleException — always when malformed, and when it’s outside supported() with strict. |
| `resolve($map, $locale = null, $mode = null, $fallbackLocale = null)` | ?string | Resolve a raw locale map through the fallback chain; null arguments default to the current locale, fallbackMode() and fallbackLocale(). Blank values never win and it never throws. |
| `fallbackMode()` | FallbackMode | translatable.fallback as an enum; not set or blank resolves to Any, an unknown value throws InvalidConfigurationException. |
| `fallbackLocale()` | string | translatable.fallback\_locale, or '' when it is not set (null or blank) — no fallback locale. |
| `fromInput($input)` | array<string, string> | A bare string becomes the current locale; blank, non-string and unsupported locales are dropped — a bare string’s locale included. |
| `rules($field, $required, $each = [])` | array | Validation rules for a locale-map field, plus $each on every locale. |
| `filledRule($field)` | list<Closure> | Only the “at least one locale is filled” rule. |
| `apply($model, $changes)` | void | Merge a TranslationChanges set in memory — supplied locales are set, the others kept; save() then writes the whole column, so the last write wins. Throws TranslationsNotLoadedException on a model loaded without the column. |
| `search($query, $search)` | Builder | Per-locale, case-insensitive, literal-substring search across fields, qualified with the model’s table so joins are safe; no fields or no supported locale matches no rows. |
| `usingLocale($locale, $callback)` | mixed | Run a closure under a temporary app locale, always restored. |

resolve() is covered under Fallback modes, ensureLocale() and the admin helpers under Input and validation, search() under Querying and search.

## Reading in another locale

usingLocale() runs a closure with the app locale temporarily switched and always restores it afterwards — even on an exception. Use it to read a model in another locale without mutating global state, e.g. in queued renders or sitemaps:

```php
use RoundlyConsulting\Translatable\Facades\Translatable;

$sk = Translatable::usingLocale('sk', fn (): string => $topic->name); // 'Investovanie'

// Every locale's resolved name — e.g. for a sitemap or a queued export:
$names = collect(Translatable::supported())->mapWithKeys(
    fn (string $locale): array => [$locale => Translatable::usingLocale($locale, fn (): ?string => $topic->name)],
);
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/translatable-for-laravel.md)
