{"id":507,"date":"2025-08-30T19:16:12","date_gmt":"2025-08-30T19:16:12","guid":{"rendered":"https:\/\/1v0.net\/blog\/?p=507"},"modified":"2025-08-30T19:16:14","modified_gmt":"2025-08-30T19:16:14","slug":"how-to-build-multi-language-i18n-support-in-laravel","status":"publish","type":"post","link":"https:\/\/1v0.net\/blog\/how-to-build-multi-language-i18n-support-in-laravel\/","title":{"rendered":"How to Build Multi-Language (i18n) Support in Laravel"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>How to Build Multi-Language (i18n) Support in Laravel 12<\/strong><\/h2>\n\n\n\n<p>Modern applications often need to serve users in multiple languages. Laravel 12 makes it easy to implement <strong>multi-language (i18n) support<\/strong> with built-in localization features. In this article, you\u2019ll configure locales, create translation files, switch languages from controllers and middleware, and add a simple language switcher UI for your Blade views.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Configure Locales in Laravel<\/strong><\/h2>\n\n\n\n<p>Set the default application language and add a fallback language in your <code>.env<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">APP_LOCALE=en\nAPP_FALLBACK_LOCALE=en<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><code>APP_LOCALE<\/code> defines the default language (English here). <code>APP_FALLBACK_LOCALE<\/code> is used if a translation is missing in the chosen language.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Create Translation Files<\/strong><\/h2>\n\n\n\n<p>Laravel stores translations under the <code>lang<\/code> directory. Each locale has its own folder. For example, create <code>lang\/en\/messages.php<\/code> and <code>lang\/es\/messages.php<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ lang\/en\/messages.php<\/span>\n<span class=\"hljs-keyword\">return<\/span> &#91;\n    <span class=\"hljs-string\">'welcome'<\/span> =&gt; <span class=\"hljs-string\">'Welcome to our application!'<\/span>,\n    <span class=\"hljs-string\">'login'<\/span> =&gt; <span class=\"hljs-string\">'Login'<\/span>,\n    <span class=\"hljs-string\">'register'<\/span> =&gt; <span class=\"hljs-string\">'Register'<\/span>,\n];<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This is the English version. Now create the Spanish version:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ lang\/es\/messages.php<\/span>\n<span class=\"hljs-keyword\">return<\/span> &#91;\n    <span class=\"hljs-string\">'welcome'<\/span> =&gt; <span class=\"hljs-string\">'\u00a1Bienvenido a nuestra aplicaci\u00f3n!'<\/span>,\n    <span class=\"hljs-string\">'login'<\/span> =&gt; <span class=\"hljs-string\">'Iniciar sesi\u00f3n'<\/span>,\n    <span class=\"hljs-string\">'register'<\/span> =&gt; <span class=\"hljs-string\">'Registrarse'<\/span>,\n];<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Each key should exist in all languages. Laravel automatically looks up the key in the current locale\u2019s file.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Using Translations in Blade Templates<\/strong><\/h2>\n\n\n\n<p>Use the <code>__()<\/code> helper or <code>@lang<\/code> directive to fetch translations inside your views:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;h1&gt;{{ __(<span class=\"hljs-string\">'messages.welcome'<\/span>) }}&lt;\/h1&gt;\n\n&lt;a href=<span class=\"hljs-string\">\"\/login\"<\/span>&gt;@lang(<span class=\"hljs-string\">'messages.login'<\/span>)&lt;\/a&gt; |\n&lt;a href=<span class=\"hljs-string\">\"\/register\"<\/span>&gt;@lang(<span class=\"hljs-string\">'messages.register'<\/span>)&lt;\/a&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>When the locale is <code>en<\/code>, this outputs English. When <code>es<\/code>, it displays Spanish text. This keeps Blade templates clean and reusable.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Switching Locales in a Controller<\/strong><\/h2>\n\n\n\n<p>You can set the current locale dynamically in a controller action, for example, when a user chooses a language preference:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Controllers<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Request<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Support<\/span>\\<span class=\"hljs-title\">Facades<\/span>\\<span class=\"hljs-title\">App<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">LanguageController<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Controller<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">switch<\/span><span class=\"hljs-params\">($locale)<\/span>\n    <\/span>{\n        <span class=\"hljs-keyword\">if<\/span> (in_array($locale, &#91;<span class=\"hljs-string\">'en'<\/span>, <span class=\"hljs-string\">'es'<\/span>])) {\n            App::setLocale($locale);\n            session(&#91;<span class=\"hljs-string\">'locale'<\/span> =&gt; $locale]);\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> redirect()-&gt;back();\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The app\u2019s locale is updated and stored in the session. Add a route like <code>\/lang\/{locale}<\/code> to switch languages dynamically.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Persisting Locale with Middleware<\/strong><\/h2>\n\n\n\n<p>Create a middleware that applies the user\u2019s preferred locale on every request:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">php artisan make:middleware SetLocale<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then implement it like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Middleware<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Closure<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Support<\/span>\\<span class=\"hljs-title\">Facades<\/span>\\<span class=\"hljs-title\">App<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SetLocale<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handle<\/span><span class=\"hljs-params\">($request, Closure $next)<\/span>\n    <\/span>{\n        $locale = session(<span class=\"hljs-string\">'locale'<\/span>, config(<span class=\"hljs-string\">'app.locale'<\/span>));\n        App::setLocale($locale);\n\n        <span class=\"hljs-keyword\">return<\/span> $next($request);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Register this middleware in <code>app\/Http\/Kernel.php<\/code>, and Laravel will automatically use the stored session locale for every request.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Building a Language Switcher UI<\/strong><\/h2>\n\n\n\n<p>Add a simple dropdown in your Blade template to let users pick a language:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;form action=<span class=\"hljs-string\">\"\/lang\"<\/span> method=<span class=\"hljs-string\">\"GET\"<\/span>&gt;\n    &lt;select name=<span class=\"hljs-string\">\"locale\"<\/span> onchange=<span class=\"hljs-string\">\"this.form.submit()\"<\/span>&gt;\n        &lt;option value=<span class=\"hljs-string\">\"en\"<\/span> {{ app()-&gt;getLocale() == <span class=\"hljs-string\">'en'<\/span> ? <span class=\"hljs-string\">'selected'<\/span> : <span class=\"hljs-string\">''<\/span> }}&gt;English&lt;\/option&gt;\n        &lt;option value=<span class=\"hljs-string\">\"es\"<\/span> {{ app()-&gt;getLocale() == <span class=\"hljs-string\">'es'<\/span> ? <span class=\"hljs-string\">'selected'<\/span> : <span class=\"hljs-string\">''<\/span> }}&gt;Espa\u00f1ol&lt;\/option&gt;\n    &lt;\/select&gt;\n&lt;\/form&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This dropdown reloads the page with the chosen locale applied. You can enhance it with Bootstrap or Tailwind to match your design system.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Using Events for Language Switching<\/strong><\/h2>\n\n\n\n<p>For audit logs or analytics, trigger an event whenever the user switches their language:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ app\/Events\/LanguageChanged.php<\/span>\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Events<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Foundation<\/span>\\<span class=\"hljs-title\">Events<\/span>\\<span class=\"hljs-title\">Dispatchable<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">LanguageChanged<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Dispatchable<\/span>;\n\n    <span class=\"hljs-keyword\">public<\/span> $locale;\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">__construct<\/span><span class=\"hljs-params\">($locale)<\/span>\n    <\/span>{\n        <span class=\"hljs-keyword\">$this<\/span>-&gt;locale = $locale;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dispatch the event from your controller when switching locales, and attach listeners to record logs or update persistent user settings.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wrapping Up<\/strong><\/h2>\n\n\n\n<p>In this guide, you configured Laravel 12 for multiple languages, created translation files, used translations in Blade, switched locales via controllers and middleware, built a dropdown UI, and fired events for language changes. Multi-language support makes your app accessible to global users and improves overall UX.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>FAQ: Multi-Language (i18n) in Laravel<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How do I change the default language in Laravel?<\/strong><br\/>Update <code>APP_LOCALE<\/code> in your <code>.env<\/code> file.<\/li>\n<li><strong>Can I use JSON files for translations?<\/strong><br\/>Yes. Laravel supports <code>lang\/{locale}.json<\/code> files for single-line key\/value translations.<\/li>\n<li><strong>How do I remember the user\u2019s preferred language?<\/strong><br\/>Store the selected locale in the session (via middleware) or in the database tied to the user profile.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What\u2019s Next<\/strong><\/h2>\n\n\n\n<p>Continue improving your app\u2019s UX and SEO with these related guides:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/blog\/creating-a-user-friendly-roles-permissions-ui-in-laravel\">Creating a User-Friendly Roles &amp; Permissions UI in Laravel<\/a><\/li>\n<li><a href=\"\/blog\/mastering-validation-rules-in-laravel-12\">Mastering Validation Rules in Laravel 12<\/a><\/li>\n<li><a href=\"\/blog\/laravel-seo-guide-optimizing-meta-slugs-sitemaps\">Laravel SEO Guide: Optimizing Meta, Slugs, and Sitemaps<\/a><\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>How to Build Multi-Language (i18n) Support in Laravel 12 Modern applications often need to serve users in multiple languages. Laravel 12 makes it easy to implement multi-language (i18n) support with built-in localization features. In this article, you\u2019ll configure locales, create translation files, switch languages from controllers and middleware, and add a simple language switcher UI [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":511,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[96,46,95,94,93],"class_list":["post-507","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","tag-blade","tag-events","tag-i18n","tag-localization","tag-translation"],"_links":{"self":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/507","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/comments?post=507"}],"version-history":[{"count":1,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/507\/revisions"}],"predecessor-version":[{"id":510,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/507\/revisions\/510"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media\/511"}],"wp:attachment":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media?parent=507"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/categories?post=507"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/tags?post=507"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}