Laravel Integration

Learn how to integrate internationalization with Laravel applications.

Integrate internationalization with your Laravel application to support multiple languages using Lengrise-managed translations, with both server-side rendering and Blade template capabilities.

Prerequisites

  • Laravel project (v8.0+)
  • PHP (v7.4+)
  • Composer
  • Translations downloaded from Lengrise

Pull Translation Files

First, you must pull your translation files from Lengrise API. These files will contain all the translated text for your application.

  1. Go to the Installation Guide and follow the steps to download your translations
  2. Place the downloaded JSON files in your project as shown in the project structure below
  3. Ensure that each language has its own JSON file named with the language code (e.g., en.json, es.json)

Integration Setup

Laravel comes with built-in internationalization support, so no additional packages are required. However, you might want to install some helpful packages:

    composer require laravel/ui
    composer require astrotomic/laravel-translatable

Project Structure

composer.jsonadd
artisanadd
appadd
Httpadd
Controllersadd
LanguageController.phpadd
Middlewareadd
SetLocale.phpadd
Providersadd
AppServiceProvider.phpadd
configadd
app.phpadd
resourcesadd
viewsadd
welcome.blade.phpadd
layoutsadd
app.blade.phpadd
componentsadd
language-switcher.blade.phpadd
langadd
enadd
messages.phpadd
validation.phpadd
esadd
messages.phpadd
validation.phpadd
en.jsonadd
es.jsonadd
jsadd
app.jsadd
i18n.jsadd
routesadd
web.phpadd

Configuration Steps

1. Configure Laravel Locale Settings

Update your config/app.php file to set the default locale and available locales:

<?php

return [
    // Other config settings...

    /*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */
    'locale' => 'en',

    /*
    |--------------------------------------------------------------------------
    | Application Fallback Locale
    |--------------------------------------------------------------------------
    |
    | The fallback locale determines the locale to use when the current one
    | is not available. You may change the value to correspond to any of
    | the language folders that are provided through your application.
    |
    */
    'fallback_locale' => 'en',

    /*
    |--------------------------------------------------------------------------
    | Available Application Locales
    |--------------------------------------------------------------------------
    |
    | The available locales determines which locales are available for the
    | application. You can provide an array of supported locales below.
    |
    */
    'available_locales' => ['en', 'es'],

    // Other config settings...
];

2. Create a Locale Middleware

Create a middleware to set the application locale based on user preferences:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;

class SetLocale
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // Get locale from session, cookie, header, or use default
        $locale = Session::get('locale', config('app.locale'));

        // You can also check for a query parameter to change the locale on-the-fly
        if ($request->has('lang') && in_array($request->lang, config('app.available_locales'))) {
            $locale = $request->lang;
            Session::put('locale', $locale);
        }

        // Set application locale
        App::setLocale($locale);

        return $next($request);
    }
}

Register this middleware in your app/Http/Kernel.php file:

protected $middlewareGroups = [
    'web' => [
        // ... other middleware
        \App\Http\Middleware\SetLocale::class,
    ],
    // ...
];

3. Create a Language Controller

Create a controller to handle language switching:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;

class LanguageController extends Controller
{
    /**
     * Switch the application language.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $locale
     * @return \Illuminate\Http\RedirectResponse
     */
    public function switch(Request $request, $locale)
    {
        // Check if the locale is supported
        if (!in_array($locale, config('app.available_locales'))) {
            return redirect()->back();
        }

        // Store the locale in session
        Session::put('locale', $locale);

        // Redirect back or to home page
        return redirect()->back();
    }
}

4. Update Routes

Add a route for language switching in your routes/web.php file:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\LanguageController;

// Home route
Route::get('/', function () {
    return view('welcome');
});

// Language switch route
Route::get('/language/{locale}', [LanguageController::class, 'switch'])->name('language.switch');

// Other routes...

5. Create Translation Files

Create language files in the resources/lang directory:

For PHP array-based translations, create resources/lang/en/messages.php:

<?php

return [
    'welcome' => 'Welcome to our application',
    'hello' => 'Hello, :name',
    'home' => 'Home',
    'about' => 'About',
    'contact' => 'Contact',
    'features' => [
        'title' => 'Features',
        'easy' => 'Easy to use',
        'fast' => 'Fast translation',
        'flexible' => 'Flexible integration',
    ],
    'items' => 'You have :count item|You have :count items',
    'footer' => [
        'copyright' => '© :year My Website. All rights reserved.',
    ],
];

And resources/lang/es/messages.php:

<?php

return [
    'welcome' => 'Bienvenido a nuestra aplicación',
    'hello' => 'Hola, :name',
    'home' => 'Inicio',
    'about' => 'Acerca de',
    'contact' => 'Contacto',
    'features' => [
        'title' => 'Características',
        'easy' => 'Fácil de usar',
        'fast' => 'Traducción rápida',
        'flexible' => 'Integración flexible',
    ],
    'items' => 'Tienes :count elemento|Tienes :count elementos',
    'footer' => [
        'copyright' => '© :year Mi Sitio Web. Todos los derechos reservados.',
    ],
];

For JSON-based translations, create resources/lang/en.json:

{
  "Welcome to our site": "Welcome to our site",
  "Features": "Features",
  "Easy to use": "Easy to use",
  "Fast translation": "Fast translation",
  "Flexible integration": "Flexible integration",
  "Hello, :name!": "Hello, :name!",
  "Switch Language": "Switch Language",
  "English": "English",
  "Spanish": "Spanish"
}

And resources/lang/es.json:

{
  "Welcome to our site": "Bienvenido a nuestro sitio",
  "Features": "Características",
  "Easy to use": "Fácil de usar",
  "Fast translation": "Traducción rápida",
  "Flexible integration": "Integración flexible",
  "Hello, :name!": "¡Hola, :name!",
  "Switch Language": "Cambiar Idioma",
  "English": "Inglés",
  "Spanish": "Español"
}

6. Create a Language Switcher Component

Create a file at resources/views/components/language-switcher.blade.php:

<div class="language-switcher">
    <span>{{ __('Switch Language') }}:</span>
    <ul>
        @foreach(config('app.available_locales') as $locale)
            <li>
                <a href="{{ route('language.switch', $locale) }}" class="{{ app()->getLocale() === $locale ? 'active' : '' }}">
                    @if($locale === 'en')
                        {{ __('English') }}
                    @elseif($locale === 'es')
                        {{ __('Spanish') }}
                    @else
                        {{ strtoupper($locale) }}
                    @endif
                </a>
            </li>
        @endforeach
    </ul>
</div>

<style>
    .language-switcher {
        margin: 1rem 0;
        display: flex;
        align-items: center;
    }
    .language-switcher ul {
        display: flex;
        list-style-type: none;
        padding: 0;
        margin: 0 0 0 10px;
    }
    .language-switcher li {
        margin-right: 1rem;
    }
    .language-switcher a {
        text-decoration: none;
        color: #333;
    }
    .language-switcher a.active {
        font-weight: bold;
        color: #0066cc;
    }
</style>

7. Update Your Layout

Update your main layout file at resources/views/layouts/app.blade.php:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@yield('title', __('Welcome to our site'))</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <!-- Styles -->
    <style>
        body {
            font-family: 'Nunito', sans-serif;
            margin: 0;
            padding: 0;
        }
        header {
            background-color: #f8f9fa;
            padding: 1rem;
            border-bottom: 1px solid #e9ecef;
        }
        header h1 {
            margin-top: 0;
        }
        nav ul {
            display: flex;
            list-style-type: none;
            padding: 0;
        }
        nav li {
            margin-right: 1rem;
        }
        main {
            padding: 1rem;
        }
        footer {
            background-color: #f8f9fa;
            padding: 1rem;
            text-align: center;
            border-top: 1px solid #e9ecef;
        }
    </style>
</head>
<body>
    <header>
        <h1>{{ __('Welcome to our site') }}</h1>
        <nav>
            <ul>
                <li><a href="/">{{ __('Home') }}</a></li>
                <li><a href="/about">{{ __('About') }}</a></li>
                <li><a href="/contact">{{ __('Contact') }}</a></li>
            </ul>
        </nav>

        @include('components.language-switcher')
    </header>

    <main>
        @yield('content')
    </main>

    <footer>
        <p>{!! __('footer.copyright', ['year' => date('Y')]) !!}</p>
    </footer>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

8. Create the Welcome Page

Update your welcome page at resources/views/welcome.blade.php:

@extends('layouts.app')

@section('title', __('Welcome to our site'))

@section('content')
    <h1>{{ __('Welcome to our site') }}</h1>

    <section>
        <h2>{{ __('Features') }}</h2>
        <ul>
            <li>{{ __('Easy to use') }}</li>
            <li>{{ __('Fast translation') }}</li>
            <li>{{ __('Flexible integration') }}</li>
        </ul>
    </section>

    <p>{{ trans_choice('messages.items', 5, ['count' => 5]) }}</p>

    <p>{{ __('Hello, :name!', ['name' => 'Laravel Developer']) }}</p>
@endsection

Working with Translations

1. Using Translations in Blade Templates

Laravel provides several ways to translate text in Blade templates:

<!-- Using the __ helper function -->
{{ __('welcome') }}

<!-- For messages with variables -->
{{ __('hello', ['name' => 'John']) }}

<!-- For nested translations -->
{{ __('features.title') }}

<!-- For pluralization -->
{{ trans_choice('messages.items', 5, ['count' => 5]) }}

2. Using Translations in PHP Code

In your controllers or other PHP code:

// Using the __ helper function
$welcome = __('welcome');

// Using the trans helper
$hello = trans('messages.hello', ['name' => 'John']);

// Using the Lang facade
use Illuminate\Support\Facades\Lang;

$title = Lang::get('features.title');

// For pluralization
$items = Lang::choice('messages.items', 5, ['count' => 5]);

3. JavaScript Translations

Laravel makes it easy to use the same translations in your JavaScript. First, create a resources/js/i18n.js file:

// Load Laravel's translations into a global variable
window.translations = {};

// Function to retrieve translation
window.__ = function (key, replacements = {}) {
  let translation = window.translations[key] || key;

  // Replace placeholders
  Object.keys(replacements).forEach((placeholder) => {
    translation = translation.replace(
      new RegExp(`:${placeholder}`, "g"),
      replacements[placeholder]
    );
  });

  return translation;
};

// Load translations when document is ready
document.addEventListener("DOMContentLoaded", function () {
  // Fetch the translations from the server
  fetch(`/js/lang/${document.documentElement.lang}.json`)
    .then((response) => response.json())
    .then((data) => {
      window.translations = data;

      // Translate elements with data-i18n attribute
      document.querySelectorAll("[data-i18n]").forEach((el) => {
        const key = el.getAttribute("data-i18n");
        const params = el.getAttribute("data-i18n-params");

        if (params) {
          el.innerText = window.__(key, JSON.parse(params));
        } else {
          el.innerText = window.__(key);
        }
      });
    });
});

Add a route to expose translations to JavaScript:

// routes/web.php
Route::get('/js/lang/{locale}.json', function ($locale) {
    $path = resource_path("lang/{$locale}.json");

    if (!file_exists($path)) {
        return response()->json([]);
    }

    return response()->json(json_decode(file_get_contents($path)));
})->name('translations');

Then include the script in your layout and use it in your HTML or JavaScript:

<!-- In your HTML -->
<div data-i18n="Welcome to our site"></div>

<!-- With parameters -->
<div
    data-i18n="Hello, :name!"
    data-i18n-params='{"name":"JavaScript User"}'
></div>

<!-- In your JavaScript -->
<script>
    const message = window.__('Welcome to our site');

    // With parameters
    const greeting = window.__('Hello, :name!', { name: 'JavaScript User' });
</script>

Resources

For more detailed information, check out these resources: