Localization In Laravel REST API


03rd September 2021 3 mins read
Share On        


Recently I wanted to support multiple language responses in my Laravel REST API project. So thought that it would be a good go for the Localization feature of Laravel.

Let me walk you through the process of how I achieved it.

You can find the code in my GitHub repository - Laravel Sanctum

Laravel Installation


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

Localization Defaults SetUp


If you want to name the locales as per standards then change the following settings under.

config/app.php

'locale' => 'en-US',
'fallback_locale' => 'en-US',


locale - Default locale is set to en-US

fallback_locale - If the locale in header passed in not found under /resources/lang/ folder then it will fallback to en-US


Localization Folder Structure


Laravel gives a fluent way to handle multiple languages in your project. Let's see how we can structure it in our project.


/laravel-localization
    /resources
        /lang
            /en-US
                auth.php

            /fr-FR
                auth.php


All the English auth messages will go in /resources/lang/en-US, French in /resources/lang/fr-FR. You can create as many as language translations.


TIP: Make sure that the /resources/lang folder (en-Us, fr-FR) must match config/app.php locale & fallback_locale.

Localization Translations Messages


Let's see what will go in our translations messages.


/resources/lang/en-Us/auth.php

<?php

return [
    /** Login */
    "blocked" => "You have been blocked.",
    "email_not_verified" => "Your email is not verified.",
    "failed" => "Invalid email or password.",
    "success" => "User authenticated successfully.",
    "throttle" => "Too many login attempts. Please try again in :seconds seconds.",

    /** Logout */
    "logout_success" => "User logged out successfully.",
];


/resources/lang/fr-FR

<?php

return [
    /** Login */
    "blocked" => "Vous avez été bloqué.",
    "email_not_verified" => "Votre email n'est pas vérifié.",
    "failed" => "Email ou mot de passe invalide.",
    "success" => "L'utilisateur s'est authentifié avec succès.",

    /** Logout */
    "logout_success" => "L'utilisateur s'est déconnecté avec succès.",
];

Headers Used From Client End (Accept-Language)


Following the standard, you will come across the Accept-Language header. You might also use like X-Language but it is an unorthodox specification.

Every time a REST API request is established then you have to add the header Accept-Language


NOTE: I have added Postman examples at the end of the article.

Create Localization Middleware


Let's create a middleware so that we can handle the Accept-Languge headers before it reaches our application code with a proper fallback


Middleware Creation Command

php artisan make:middleware Localization


Registering Middleware

App/Http/Kernel.php

protected $routeMiddleware = [
    //...
    'localization' => Localization::class,
];


App / Http / Middleware / Localization.php

public function handle(Request $request, Closure $next)
{
    /** 
     * requests hasHeader is used to check the Accept-Language header from the REST API's
     */
    if ($request->hasHeader("Accept-Language")) {
        /**
         * If Accept-Language header found then set it to the default locale
         */
        App::setLocale($request->header("Accept-Language"));
    }
    return $next($request);
}


NOTE: You can use App::getLocale() to know which locale you are currently using anywhere in your application.

Middleware Usage in api.php


api.php

Route::middleware("localization")->group(function () {
    Route::group(["prefix" => "auth", "as" => "auth."], function () {
        Route::post("/authenticate", [LoginController::class, "authenticate"])->name("authenticate");
        //... other routes
    });
    Route::middleware("auth:sanctum")->group(function () {
        //... other routes
    });
});

How To Use Localization Messages


You can display any message with the help of the following way.

__("filename.message_name");

filename -> from which file you want to use

message_name -> which message key do you want to access


As we have already set the locale in Localization middleware via Accept-Language. The messages will be displayed appropriately.


if ($user->is_blocked) {
    throw new UserIsBlockedException(__("auth.blocked"));
}


if (!$user->is_email_verified) {
    throw new UserEmailNotVerifiedException(__("auth.email_not_verified"));
}


if (!Hash::check($request->get("password"), $user->password)) {
    throw new Exception(__("auth.failed"));
}


public function logout()
{
    request()->user()->tokens()->delete();
    return response()->json([
        "status"    => "success",
        "message"   => __("auth.logout_success"),
    ], Response::HTTP_OK);
}


Laravel REST API Localization Response in French


Laravel REST API Localization Response in English





AUTHOR

Channaveer Hakari

I am a full-stack developer working at WifiDabba India Pvt Ltd. I started this blog so that I can share my knowledge and enhance my skills with constant learning.

Never stop learning. If you stop learning, you stop growing