Laravel Framework provides a ton of features out of the box to get you started with building enterprise-level web applications. One such feature is out of the box support for Localization. In other words, Laravel’s localization feature makes your application multi-lingual by providing an easy way to implement support for multiple languages. In this tutorial, we’ll show you how to cater to international users by enabling auto localization in Laravel based on user location. We’ll also show you how to allow users to set their preferred language.

We will start with a new Laravel application. After that, we will change the application’s language based on the country that the user is visiting the application. To achieve this, we determine the user’s location based on their IP address and show a localized page accordingly.

Laravel Application Setup

Install a new Laravel project

composer create-project --prefer-dist laravel/laravel laravel-auto-localization

Generate application key using artisan

php artisan key:generate

Composer Package Setup

We will start by pulling in a Laravel package to help us determine the user’s location based on their IP address.

Install Torann/laravel-geoip using Composer:

composer require torann/geoip

Register Service Provider

Register the package’s service provider in config/app.php:

  'providers' => [
        ...
        /*
         * Package Service Providers...
         */

        \Torann\GeoIP\GeoIPServiceProvider::class,
        ...
  ]

Leverage the package’s Facade

The torann\geoip package comes with an optional facade. Therefore, we will register this facade under the aliases key in config/app.php.

'aliases' => [
    ...
    'GeoIP' => \Torann\GeoIP\Facades\GeoIP::class,

];

Publish the package’s configuration file

The following command will generate a geoip.php file in the `config` directory. After that, we can customize the package’s behavior in this application.

php artisan vendor:publish --provider="Torann\GeoIP\GeoIPServiceProvider" --tag=config

There is one important fix required to make this package work out of the box. That is to say, you need to set cache_tags to the following value in geoip.php:

'cache_tags' => [],

Adding Language Files

Laravel’s Localization feature looks for key-value strings defined in resources/lang directory by default. Here you can define one or more languages that your application wants to support. However, note that the language files should be placed within a sub-directory with the ISO_639-2 name of the corresponding language.

You can use Google Translate to get translations for different languages.

  • resources/lang/en:
<?php

return [
    'welcome' => 'Welcome to our application!',
    'bye' => 'We hope to see you back again soon!'
];
  • resources/lang/es:
<?php

return [
    'welcome' => 'Bienvenido a nuestra aplicación!'
    'bye' => '¡Esperamos verte de nuevo pronto!'
];
  • resources/lang/de:
<?php

return [
    'welcome' => 'Willkommen zu unserer Bewerbung!'
    'bye' => 'Wir hoffen, Sie bald wieder zu sehen!'
];

Note: If you want to support languages that differ by territory, you should name the language directories as per ISO 15897. For example, “en_In” should be used for Indian English rather than “en-in”.

From Laravel Documentation

Modifying the View

We will modify the welcome.blade.php and include the strings we defined in our language files.

<div class="content">
    <div class="title m-b-md">
        Laravel
    </div>

    <div class="title m-b-md">
        {{ __('message.welcome') }}
    </div>
</div>

Now visit your Laravel app’s homepage and you should see the welcome message displayed with the default language. Note, if you’re developing on a local server, you can start the webserver using artisan and visit http://localhost:8000/ .

Here is an example:

Laravel Localization - English

Setting Localization Based on User Location

Traditionally, to change a Laravel application’s localization language. you had to use the App facade, such as this:

App::setLocale('en');

However, to dynamically change our application’s locale, we will be hooking into Laravel’s boot() method. The boot method is empty and is defined in app/Providers/AppServiceProvider.php

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    //Check for 'lang' cookie
    $cookie = \Crypt::decrypt(\Cookie::get('lang'), false);

    //Get visitors IP
    $userIp = \Request::ip();

    //Get visitors Geo info based on his IP
    $geo = \GeoIP::getLocation($userIp);


    if($geo == null) {
        //Probably a localhost server, set language to english

        //set locale from cookie if exists
        if (!isset($cookie) && !empty($cookie)) {
            \App::setLocale($cookie);
            return;
        }

        \App::setLocale('es');
    }

    // //Get visitors country name
    $userCountry = $geo['country'];


    //Set language based on country name
    // You can add as many as you want
    $supportedLanguages = [
        'United States' => 'en',
        'Canada' => 'en',
        'India' => 'en',
        'Argentina' => 'es',
        'Spain' => 'es',
        'Chile' => 'es',
        'Austria' => 'de',
        'Luxembourg' => 'de',
        'Belgium' => 'de',
        'Germany' => 'de',
    ];

    if (!empty($cookie)) {
        dd($cookie);
        //User has manually chosen a lang. We set it
        \App::setLocale($cookie);
    } else {

        //Check country name in supportedLanguages array
        if (array_key_exists($userCountry, $supportedLanguages)) {
            //Get userCountry value(language) from array
            $preferredLang = $supportedLanguages[$userCountry];
            //Set language based on value
            \App::setLocale($preferredLang);
        } else {
            //If user is visiting from an unsupported country, default to English
            \App::setLocale('en');
        }
    }
}

There are a couple of things happening in the above function. We cover 3 scenarios here:

User with no language preference:

  1. We have a predefined list of supported countries and their respective languages.
  2. We fetch the user’s IP address and fetch the country based on the IP address.
  3. If the user’s country is among one of our supported countries, we set the application’s language to the respective country’s language.
  4. If the user is from an unsupported country, we set the user language to default English language.

User with language preference:

  1. The User has deliberately chosen his language. Therefore, a lang cookie has been stored in the browser with this user’s language preference as the value.
  2. We set this language as the application’s language. As a result, whenever the user visits our application, their language will be set as per their preference. We will ignore the country they access the application from.

Local server:

  • During development, if we are using a local server (localhost), the package fails to fetch the country. In such cases, we will set the language to English.

Allowing Users to Choose their Own Language

Sometimes the user might want to set their own language preference. For instance, if a user travels to some other country, their language preference should remain the same.

We will achieve this by defining a custom route to change the user’s preferred language. To clarify, this works by having a cookie store the user’s language preference. As cookies are browser-specific, this results in every user having their own language preference.

Create new controller for language preference

php artisan make:controller LanguagePreferenceController

Define a setLanguage() method in your LanguagePreferenceController

<?php

  namespace App\Http\Controllers;

  use Illuminate\Http\Request;
  use Cookie;
  use App;

  class LanguagePreferenceController extends Controller
  {

      public function setLanguage($lang) {

        $supportedLocales = ['en', 'es', 'de'];

        if (in_array($lang, $supportedLocales)) {
    
            \Cookie::queue(\Cookie::make('lang', $lang, '20160'));
            
            \App::setLocale($lang);
    
        } else {
            \App::setLocale('en');
        }
    
        return back();

      }
  }

In the method defined above, we check whether the user has chosen a supported language. After that, we set the cookie to the selected language and redirect back to the home page. If the user selects a language that the application doesn’t support, we set it to the default which, in this case, will be English.

Define a route that points to the method defined above

Route::get('/language/{lang}', 'LanguagePreferenceController@setLanguage');

Now we can start testing if the functionality is working as expected. Follow these basic steps to verify:

  1. Go to localhost:8000/ : You should see a welcome page with your country’s language or the default English language. Secondly, you can also emulate visits from different countries by using a VPN that changes your IP address.Laravel Localization - English
  2. Go to localhost:8000/language/es: You will be redirected back to the home page and the application’s language should now be Spanis.
    Laravel Localization - Spanish
  3. Reload localhost:8000/ : To make sure the language preference is persistent.

That’s it!, we have now implemented auto localization in Laravel based on a user’s location. If you have any doubts, please feel free to ask in the comments section below. Also, the complete source code for this tutorial is available on my GitHub repository.

And if you are a Laravel enthusiast like me, you should check out my recent article on sending telegram notifications in Laravel, or you can also check out other Laravel related tutorials!