Back to Course |
Filament 3 From Scratch: Practical Course

Multi-language: System Texts, Labels, Menus

If you work with multi-language projects in Filament, there's not much you need to learn, as Filament primarily relies on Laravel Localization features. But I will briefly demonstrate to you how it works.


Filament "System" Translations

Filament has many components translated into many languages: buttons, labels, menu items, etc.

So, you can just change the system locale in Laravel, and Filament will automatically apply the new translated texts.

config/app.php

'locale' => 'en',
'locale' => 'lt',

Here's how the Filament dashboard will look now, with some system words translated into my Lithuanian language:

But, of course, the rest is up to you to translate all the things manually.

If you want to edit those system translations, you need to publish them, it's part of the installation process, but you may also do it later.

php artisan vendor:publish --tag=filament-panels-translations

Then you will have a lot of language files in /lang/vendor/filament-panels:

Inside each language, you will see a structure of files. They are pretty self-explanatory in their purpose. Each file is a PHP array:

So you can try to edit any value, and it will be shown on the page:

lang/vendor/filament-panels/lt/resources/pages/create-record.php:

return [
 
'title' => 'Sukurti :label',
'title' => 'Naujas :label',
 
// ...
];

Here's the result:


Translating Labels

Of course, those system texts are only part of the translation work.

If you work with non-English or multi-language projects or even plan your current project to be multi-language, I advise you to use the __() method for all your static texts. In fact, I give this advice for any Laravel project, not only Filament.

For example, you could do this:

app/Filament/Resources/ProductResource.php:

Forms\Components\Wizard::make([
Forms\Components\Wizard\Step::make(__('Main data'))
->schema([
// ...
]),
Forms\Components\Wizard\Step::make(__('Additional data'))
->schema([
// ...
]),
])

Then, you must translate those "Main data" and "Additional data" in your /lang files.

Again, it goes back to Laravel functionality, but I will remind you. You must create a file lang/lt.json (change "lt" with your language) and fill it in as a key-value set.

{
"Main data": "Pagrindiniai duomenys",
"Additional data": "Papildomi duomenys"
}

Then refresh the page and see the translated texts!

The benefit of such a JSON-based structure is that someone else in the future may create their own XX.json with another language easily and switch to another language without changing anything in the Filament code.

To translate the values of forms/tables, many form/table methods like XXXXX::make() have a method ->label() where you specify the translated value, like ->label(__('Product Name')).

app/Filament/Resources/ProductResource.php:

Forms\Components\Wizard\Step::make(__('Main data'))
->schema([
Forms\Components\TextInput::make('name')
->label(__('Product name'))
->required()
->unique(ignoreRecord: true),

lang/lt.json:

{
"Main data": "Pagrindiniai duomenys",
"Additional data": "Papildomi duomenys",
"Product name": "Pavadinimas"
}

This is the result:


Translating Auto-Generated Texts

Of course, there are more things to translate, some of them generated automatically by Filament. You would need to read the official documentation on how to translate them.

For example, for menu items, you may override the $navigationLabel property:

app/Filament/Resources/ProductResource.php:

protected static ?string $navigationLabel = 'All products';

But the problem is that PHP doesn't allow to use methods for the default values of properties, so this would throw an error:

protected static ?string $navigationLabel = __('Products');

But Filament allows us to override the value in a method called getNavigationLabel():

app/Filament/Resources/ProductResource.php:

public static function getNavigationLabel(): string
{
return __('Products');
}

lang/lt.json:

{
"Main data": "Pagrindiniai duomenys",
"Additional data": "Papildomi duomenys",
"Products": "Produktai"
}

The result:

So yeah, translating all the project is pretty hard work, doing it word by word, but I hope in this lesson you got the main idea of how it works.