How to use language slug in laravel URL and set directions

How to use language slug in laravel URL and set directions

I’ve been looking for the solution to add language slug into URL for months, I’ve searched lots of pages on Google, Bing, Duck Duck, Stack Overflow and I’ve found some solutions but unfortunately none of them worked for me or at least I didn’t find them fit to my requires. But fortunately that leads me to working solution which I'm about to share with you now.

 

What I will cover in this tutorial?

  1. Add language slug such as: en, ar, fa, fr, gb etc. into url like: domain.xyz/en, domain.xyz/fa etc.
  2. Avoid route conflicts on requests
  3. Get default language on user visit (before user select any language)
  4. Get user preferred language by sessions

Extra cover:

  1. Add RTL, LTR direction based on selected language

Files to create or edit:

  1. Config ->app.php
  2. http->kernel.php
  3. controllers->LocalizationController.php
  4. middleware-> localization.php
  5. Providers->RouteServiceProvider.php

Let’s begin:

Firs we make our files and step by step we will edit each one of them, to create our required files use codes below:

Php artisan make:controller LocalizationController

Php artisan make:middleware localization

Now go to app->http->controllers and open LocalizationController.php

Add function below and save the file:

Use App;
public function index($locale)
{
  App::setLocale($locale);
  session()->put('locale', $locale);
  return redirect()->back();
}

This function will save our locale to session in order to get user locale for all routes.

 

Now go to app->http->middlewares  and open Localization.php

Replace handle with code below and save the file:

public function handle($request, Closure $next)
{
  // Make sure current locale exists.
  $locale = $request->segment(1);

  if ( ! array_key_exists($locale, app()->config->get('app.locales'))) {
    $segments = $request->segments();
    $segments[0] = app()->config->get('app.fallback_locale');

    return redirect()->to(implode('/', $segments));
  }

  app()->setLocale($locale);

  return $next($request);
}

Here we get array of supported languages and add them to our application locale, we will use this middleware in 2 cases 1- when user first visit our website we return default locale 2- when user selects a locale we return user chosen local for them. (this function will be completed in next steps)

Don’t forget to add these at the top of the file:

use Closure;
use App;
use Config;
use Session;
use Illuminate\Http\Request;

Add Localization middleware to kernel file (placed in: app->http) and save it:

protected $middlewareGroups = [
  'web' => [
    ……
    \App\Http\Middleware\Localization::class,
  ],

Open RouteServiceProvider.php from app->providers and edit mapWebRoutes function like code below:

protected function mapWebRoutes()
{
  $locale = \Request::segment(1);
  app()->setLocale($locale);

  Route::middleware('web')
    ->namespace($this->namespace)
    ->prefix($locale)
    ->group(base_path('routes/web.php'));
}

This is almost important part of this tutorial, with function above you are getting locales as prefix for all routes including authentication route (which I found many have issue to get login, register routes with locales).

One of privileges of using route prefix in RouteServiceProvider.php is that you don’t need to provide custom routes or URLs for your JavaScript actions, you just make your ajax URL just like when you don’t use any prefix, because prefixes now are returning automatically.

Last but not least open config->app.php and add code below:

'locales' => [
  'en' => 'English',
  'ar' => 'Arabic',
  'fa' => 'Persian',
  'id' => 'Indonesian',
  'ru' => 'Russian'
],

This is array of your supported language, change it to your own version.

 

As I promised in our Instagram account this article comes with +1,

How to set Directions?

 

I’ve seen this question in large amount in Stack Overflow that users want to change their app direction between LTR and RTL depend on selected locale. Well here is easiest way to do that.

 

All you need to do is to open your app layout file from resources->views->layouts and add this code to <html> tag:

{{ (str_replace('_', '-', app()->getLocale()) == 'fa') || (str_replace('_', '-', app()->getLocale()) == 'ar') ? "dir=rtl" : "dir=ltr" }}

Your full code will be like:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" {{ (str_replace('_', '-', app()->getLocale()) == 'fa') || (str_replace('_', '-', app()->getLocale()) == 'ar') ? "dir=rtl" : "dir=ltr" }}>
//rest of the code

Note: in this sample I supported Persian and Arabic languages to be RTL and the rest of the locales to be LTR you can edit this code based on your need in order to add/remove RTL languages such as Hebrew etc.

 

Please let me know what you think of this tutorial in comments below.

Share:

Leave a comment

Enjoy this?

Subscribe our newsletter and get latest updates straight to your inbox.