# Laravel Localization [](https://gitter.im/mcamara/laravel-localization?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://packagist.org/packages/mcamara/laravel-localization) [](https://packagist.org/packages/mcamara/laravel-localization) [](https://travis-ci.org/mcamara/laravel-localization) [](https://www.codetriage.com/mcamara/laravel-localization) [](https://houndci.com) Easy i18n localization for Laravel, an useful tool to combine with Laravel localization classes. The package offers the following: - Detect language from browser - Smart redirects (Save locale in session/cookie) - Smart routing (Define your routes only once, no matter how many languages you use) - Translatable Routes - Supports caching & testing - Option to hide default locale in url - Many snippets and helpers (like language selector) ## Table of Contents - Installation - Usage - Redirect Middleware - Helpers - Translated Routes - Caching routes - Testing - Common Issues - POST is not working - MethodNotAllowedHttpException - Validation message is always in default locale - Collaborators - Changelog - License ## Laravel compatibility Laravel | laravel-localization :-------------|:---------- 4.0.x | 0.13.x 4.1.x | 0.13.x 4.2.x | 0.15.x 5.0.x/5.1.x | 1.0.x 5.2.x-5.4.x (PHP 7 not required) | 1.2.x 5.2.x-5.8.x (PHP version >= 7 required) | 1.3.x 5.2.0-6.x (PHP version >= 7 required) | 1.4.x 5.2.0-9.x (PHP version >= 7 required) | 1.7.x ## Installation Install the package via composer: `composer require mcamara/laravel-localization` For Laravel 5.4 and below it necessary to [register the service provider](/ADDITIONS.md#for-laravel-5.4-and-below). ### Config Files In order to edit the default configuration you may execute: ``` php artisan vendor:publish --provider="Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider" ``` After that, `config/laravellocalization.php` will be created. The configuration options are: - **supportedLocales** Languages of your app (Default: English & Spanish). - **useAcceptLanguageHeader** If true, then automatically detect language from browser. - **hideDefaultLocaleInURL** If true, then do not show default locale in url. - **localesOrder** Sort languages in custom order. - **localesMapping** Rename url locales. - **utf8suffix** Allow changing utf8suffix for CentOS etc. - **urlsIgnored** Ignore specific urls. ### Register Middleware You may register the package middleware in the `app/Http/Kernel.php` file: ```php \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class, 'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class, 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class, 'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class, 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class ]; } ``` ## Usage Add the following to your routes file: ```php // routes/web.php Route::group(['prefix' => LaravelLocalization::setLocale()], function() { /** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/ Route::get('/', function() { return View::make('hello'); }); Route::get('test',function(){ return View::make('test'); }); }); /** OTHER PAGES THAT SHOULD NOT BE LOCALIZED **/ ``` Once this route group is added to the routes file, a user can access all locales added into `supportedLocales` (`en` and `es` by default). For example, the above route file creates the following addresses: ``` // Set application language to English http://url-to-laravel/en http://url-to-laravel/en/test // Set application language to Spanish http://url-to-laravel/es http://url-to-laravel/es/test // Set application language to English or Spanish (depending on browsers default locales) // if nothing found set to default locale http://url-to-laravel http://url-to-laravel/test ``` The package sets your application locale `App::getLocale()` according to your url. The locale may then be used for [Laravel's localization features](http://laravel.com/docs/localization). You may add middleware to your group like this: ```php Route::group( [ 'prefix' => LaravelLocalization::setLocale(), 'middleware' => [ 'localeSessionRedirect', 'localizationRedirect', 'localeViewPath' ] ], function(){ //... }); ``` ### Recommendations ***1.***: It is **strongly** recommended to use a [redirecting middleware](#redirect-middleware). Urls without locale should only be used to determine browser/default locale and to redirect to the [localized url](#localized-urls). Otherwise, when search engine robots crawl for example `http://url-to-laravel/test` they may get different language content for each visit. Also having multiple urls for the same content creates a SEO duplicate-content issue. ***2.***: It is **strongly** recommended to [localize your links](#localized-urls), even if you use a redirect middleware. Otherwise, you will cause at least one redirect each time a user clicks on a link. Also, any action url from a post form must be localized, to prevent that it gets redirected to a get request. ## Redirect Middleware The following redirection middleware depends on the settings of `hideDefaultLocaleInURL` and `useAcceptLanguageHeader` in `config/laravellocalization.php`: ### LocaleSessionRedirect Whenever a locale is present in the url, it will be stored in the session by this middleware. If there is no locale present in the url, then this middleware will check the following - If no locale is saved in session and `useAcceptLanguageHeader` is set to true, compute locale from browser and redirect to url with locale. - If a locale is saved in session redirect to url with locale, unless its the default locale and `hideDefaultLocaleInURL` is set to true. For example, if a user navigates to http://url-to-laravel/test and `en` is the current locale, it would redirect him automatically to http://url-to-laravel/en/test. ### LocaleCookieRedirect Similar to LocaleSessionRedirect, but it stores value in a cookie instead of a session. Whenever a locale is present in the url, it will be stored in the cookie by this middleware. In there is no locale present in the url, then this middleware will check the following - If no locale is saved in cookie and `useAcceptLanguageHeader` is set to true, compute locale from browser and redirect to url with locale. - If a locale is saved in cookie redirect to url with locale, unless its the default locale and `hideDefaultLocaleInURL` is set to true. For example, if a user navigates to http://url-to-laravel/test and `de` is the current locale, it would redirect him automatically to http://url-to-laravel/de/test. ### LaravelLocalizationRedirectFilter When the default locale is present in the url and `hideDefaultLocaleInURL` is set to true, then the middleware redirects to the url without locale. For example, if `es` is the default locale, then http://url-to-laravel/es/test would be redirected to http://url-to-laravel/test and the`App::getLocale()` would be set to `es`. ## Helpers This package comes with a bunch of helpers. ### Localized URLs Localized URLS taken into account [route model binding]([https://laravel.com/docs/master/routing#route-model-binding]) when generating the localized route, aswell as the `hideDefaultLocaleInURL` and [Translated Routes](#translated-routes) settings. #### Get localized URL ```php // If current locale is Spanish, it returns `/es/test` @lang('Follow this link') ``` #### Get localized URL for an specific locale Get current URL in specific locale: ```php // Returns current url with English locale. {{ LaravelLocalization::getLocalizedURL('en') }} ``` ### Get Clean routes Returns a URL clean of any localization. ```php // Returns /about {{ LaravelLocalization::getNonLocalizedURL('/es/about') }} ``` ### Get URL for an specific translation key Returns a route, [localized](#translated-routes) to the desired locale. If the translation key does not exist in the locale given, this function will return false. ```php // Returns /es/acerca {{ LaravelLocalization::getURLFromRouteNameTranslated('es', 'routes.about') }} ``` ### Get Supported Locales Return all supported locales and their properties as an array. ```php {{ LaravelLocalization::getSupportedLocales() }} ``` ### Get Supported Locales Custom Order Return all supported locales but in the order specified in the configuration file. You can use this function to print locales in the language selector. ```php {{ LaravelLocalization::getLocalesOrder() }} ``` ### Get Supported Locales Keys Return an array with all the keys for the supported locales. ```php {{ LaravelLocalization::getSupportedLanguagesKeys() }} ``` ### Get Current Locale Return the key of the current locale. ```php {{ LaravelLocalization::getCurrentLocale() }} ``` ### Get Current Locale Name Return current locale's name as string (English/Spanish/Arabic/ ..etc). ```php {{ LaravelLocalization::getCurrentLocaleName() }} ``` ### Get Current Locale Native Name Return current locale's native name as string (English/Español/عربى/ ..etc). ```php {{ LaravelLocalization::getCurrentLocaleNative() }} ``` ### Get Current Locale Regional Name Return current locale's regional name as string (en_GB/en_US/fr_FR/ ..etc). ```php {{ LaravelLocalization::getCurrentLocaleRegional() }} ``` ### Get Current Locale Direction Return current locale's direction as string (ltr/rtl). ```php {{ LaravelLocalization::getCurrentLocaleDirection() }} ``` ### Get Current Locale Script Return the [ISO 15924](http://www.unicode.org/iso15924) code for the current locale script as a string; "Latn", "Cyrl", "Arab", etc. ```php {{ LaravelLocalization::getCurrentLocaleScript() }} ``` ### Set view-base-path to current locale Register the middleware `LaravelLocalizationViewPath` to set current locale as view-base-path. Now you can wrap your views in language-based folders like the translation files. `resources/views/en/`, `resources/views/fr`, ... ### Map your own custom lang url segments As you can modify the supportedLocales even by renaming their keys, it is possible to use the string ```uk``` instead of ```en-GB``` to provide custom lang url segments. Of course, you need to prevent any collisions with already existing keys and should stick to the convention as long as possible. But if you are using such a custom key, you have to store your mapping to the ```localesMapping``` array. This ``` localesMapping``` is needed to enable the LanguageNegotiator to correctly assign the desired locales based on HTTP Accept Language Header. Here is a quick example how to map HTTP Accept Language Header 'en-GB' to url segment 'uk': ```php // config/laravellocalization.php 'localesMapping' => [ 'en-GB' => 'uk' ], ``` After that ```http://url-to-laravel/en-GB/a/b/c``` becomes ```http://url-to-laravel/uk/a/b/c```. ```php LaravelLocalization::getLocalizedURL('en-GB', 'a/b/c'); // http://url-to-laravel/uk/a/b/c LaravelLocalization::getLocalizedURL('uk', 'a/b/c'); // http://url-to-laravel/uk/a/b/c ``` ## Creating a language selector If you're supporting multiple locales in your project you will probably want to provide the users with a way to change language. Below is a simple example of blade template code you can use to create your own language selector. ```blade