When you show a translation string, Laravel needs to know what language to load, right? In tech terms, it's called "locale", and each Laravel project has the primary and the fallback locales.
In this lesson, we'll cover how to set them.
Setting The Locale
To set the default locale is simple - just open the config/app.php
and modify the locale
key:
config/app.php
'locale' => 'es',// Or any other shortcode.// It has to match with the `lang/FOLDER` folder name// or the `lang/KEY.json` name.
This will be your application's default language for all users. Don't leave it as en
if you are building an application with a different language.
Setting The Fallback Locale
In this example, we've set our application to use es
as a default language, but it's missing some translations:
Translations will return the full key by default unless you set a fallback locale:
config/app.php
'fallback_locale' => 'en',
Then it will take the fallback language and load its text:
lang/en/auth.php
return [ // ... 'register' => 'Registration',];
Which will result in the following:
Now we see that Register
is used instead of the key. While this is not perfect because it's not in Spanish, it's better than showing the key to the user.
JSON Translations are Different
Now here's the catch for JSON file-based translations. They don't really have a fallback as you would expect. It will not go to the fallback language, rather it will just display the key output.
In the same scenario, I've used JSON files instead of .php
files for translations and fallback did nothing. Here's what it did:
Changed the text to Registration
:
lang/en.json
{ "Register": "Registration"}
Configured the locale and fallback locale:
config/app.php
'locale' => 'es','fallback_locale' => 'en',
But this still displays Register
instead of Registration
that's defined in en
language:
This is because JSON tried to look for a translated value in the es.json
file, but it didn't find it. So it just displayed the key.
To illustrate this even more, let's say we are trying to look for:
<a href="{{ route('register') }}" class="ml-4 font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500"> {{ __('Register to Join our Community') }}</a>
And we have a translation for this in en.json
:
lang/en.json
{ "Register to Join our Community": "Sign up to join our community"}
What do you think the output will be? "Sign up to join our community"
or "Register to Join our Community"
. Since we have a translation fallback - we'd expect the Sign up...
to be displayed. But it displays this:
We did not get what we expected as JSON doesn't look for fallback language or at least it doesn't do it in the same way as PHP files do.
Setting the Locale Dynamically in Code
For multi-language projects, the locale should be set by user preference or URL. Then we should use this code:
use Illuminate\Support\Facades\App; // ... if(! in_array($locale, ['en', 'es'])) { abort(404);} App::setLocale($locale); // ...
You would ask, where to place it?
This can be placed anywhere, but in my experience, it's best to place it in Middleware. We will cover a practical example of this later, in our lesson about UI-based Language switching.
In general, as soon as you start working with multi-language applications - you need to pick one language as your primary source of truth. This should become your fallback language. It will help you spot missing translations and will prevent users from seeing random translation keys.
No comments or questions yet...