How to build a multilingual PHP app with Localazy and Laravel

Software localization adjusts software to a target market's cultural, linguistic, and technical demands to gain a competitive advantage, long-term sales increase, and better customer retention. This process frequently requires a tremendous amount of time from the development teams and is work exhaustive, right? Not if you're working with Localazy, we automate the localization process for you, making it so much easier to conquer your target markets 👑.

💭 Why Localazy and Laravel?

Localazy is a developer-focused localization management platform that supports a wide variety of frameworks and an even more comprehensive range of formats through its CLI.

Localazy’s best features

  • A pro-active review process.
  • Highly accurate translation memory supported by community-shared translations.
  • A simple, crystal clear UI that is not bloated with rarely used options.

We support the Laravel framework, which is without a doubt the most used one for PHP apps but is also considered one of the top web development frameworks.

🧭 Localazy and Laravel Integration: How?

The code we’ll use is supposed to demonstrate the general concept, so feel free to take any part of it and adapt it to your own project’s specific needs.

For this tutorial, we’ll use a Windows 10 machine, but you can accomplish the same with the other operating systems supported by the Localazy CLI, we’ll also use Laravel version 8.5.15.

Creating a new Laravel project

We’ll start this tutorial by creating an empty project on Laravel using Composer. We’ll go step by step to every detail showing you how to integrate a Laravel project with Localazy from the get-go.

Open your cmd and navigate it to the directory where you want to create the project.

I’ll use the htdocs folder on our XAMPP directory, but feel free to use your own.

You do not need XAMPP installed as Laravel has it’s own local development server.

![](upload://4cg0jgrmemCFninZ3VXqWdQlsiC.png)

We’ll run the command composer create-project laravel/laravel example-app to create our new project in our desired directory.

![](upload://5XhR2tmmgEtLj1RzE8OuUn5Gs4l.png)

If everything worked properly, this is your new project’s directory:

![](upload://52xzBSXAoF8VkyUFSVvE2zNzqgQ.png)

On Laravel default projects, there’s a very special ✨ folder for our Localization process, that is example-appresources\lang. The lang folder will contain the supported languages for your project, and by default, it only contains English, as we can see by the en folder.

![](upload://ekehwYFEsjVwzmTLTNcas8wq04U.png)

Before adding any new languages and starting our localization journey, we need an actual project to translate.

So we’ll create a php file inside example-app\resources\views and we’ll name it example.blade.php. You can ignore or delete the welcome.blade.php file inside the views directory as it is useless for our example.

![](upload://2MLSYhQhYs5ACNRogIO10xYn6dA.png)

Inside our example.blade.php we’ll write the following code in HTML and PHP with some different strings:

<h1>Welcome to our Localazy translation tutorial</h1>
<?php
echo "<h2>PHP is Fun!</h2>";
echo "Hello world!<br>";
$x = 30;
$string_1 = "How old are you? <br>";
$string_2 = "I am $x years old <br>";
echo $string_1;
echo $string_2;
?>
<br>
<a href="#"> This is an anchor tag </a>

We kept it very basic for demonstration purposes.

To see what we wrote on our browser, we need to configure our web.php file inside example-app\routes. We have to open the file and add Route::view('example', 'example');. The file then will contain the following code:

<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
Route::view('example','example');

Now we’ll use Laravel’s local development server to show what we have in the browser. To start the server, all we have to do is execute PHP artisan serve in the project’s root.

This is how it should look:

![](upload://8ETNiQI3Jr5upt8NJq7cC1MOUgv.png)

We can now open our browser and enter localhost:8000/example. If we have followed all the steps correctly, we will now see the following page:

![](upload://FNnJyTnII4WHf838FgWZXXWxTm.png)

Adding the source language

Right, the browser shows the strings, but how are we going to translate everything we wrote? We’re going to open the en folder in example-app\resources\lang, and here we will create the file example.php, and this file will contain all our strings in English, our source language.

Inside the file, we’ll write this code:

<?php
return [
  'welcome'=>">Welcome to our Localazy translation tutorial",
  'php_fun'=>"PHP is Fun!",
  'hello'=>"Hello world!",
  'how_old_question'=>"How old are you?",
  'how_old_answer'=>"I am :years years old",
  'anchor'=>"This is an anchor tag",
]
 ?>

What we did is that we gave a key to each string we want to translate. We will use the key to locate the translated string and use it in the localization process.

We also used a variable to show how we can translate the string without affecting the variable usage, so we had to set a placeholder on the example.php file using the prefix :.

Now we’ll have to tell our project where to get the strings from. Open the example.blade.php file and switch all the strings with the key name that we just set.


<h1>{{__('example.welcome')}}</h1>
<?php
echo "<h2>".__('example.php_fun')."</h2>";
echo __('example.hello'). "<br>";
$x = 30;
$string_1 = __('example.how_old_question'). "<br>";
$string_2 = __('example.how_old_answer', ['years' => $x]). "<br>";
echo $string_1;
echo $string_2;
 ?>
 <br>
 <a href="#"> {{__('example.anchor')}} </a>

We’ve used HTML and PHP examples to show the correct format for both cases.

For the variable to work correctly, we need to use [ ] and define the placeholder’s variable.

Your browser’s page will look like this:

![](upload://FNnJyTnII4WHf838FgWZXXWxTm.png)

Yes, it should look exactly like before because we just localized our project, giving it a format that enables us to use Localazy’s features.

Integrating Localazy with our project

Now comes the fun part. Now we will download and install the Localazy CLI. We’ll use Windows 10 for the demonstration. The process might be different from the other operating systems. But on the Localazy CLI installation page, there’s all the information to proceed with another OS.

After downloading the CLI, place it inside the root directory of the project.

Note that this example is for Windows, so download and paste the .exe in the project’s root.

![](upload://rvXxJHFd5wHg3Lswq5kN1hKeSew.png)

Proceed to register if you don’t have a Localazy account or log in and create a new app.

![](upload://eFE3iuBTx8MMkz0pG1YHPM2VLT3.png)

You’ll now have to choose your integration which in this case is obviously Laravel.

![](upload://yNm6MkSJ5dzdyl0IzgqydxRx3MX.png)

When you choose the integration, you’ll receive a write-key and a read-key with the following code:

{
  "writeKey": "your-apps-write-key",
  "readKey": "your-apps-read-key",
  "upload": {  
    "type": "php",
    "files": "translations/strings.php"         
  },
  "download": {
    "files": "translations/${lang}.php"
  }
}

We will use the code above in a localazy.json file for the configuration of the integration. We need to create the localazy.json file in the directory root with the Locality CLI, and we’ll configure it to upload and download the strings on our chosen directory with the following code:

{
  "writeKey": "your-apps-write-key",
  "readKey": "your-apps-read-key",
  "upload": {
    "type": "php",
    "files": "/resources/lang/en/example.php"
  },
  "download": {
    "files": "/resources/lang/${lang}/example.php"
  }
}

The localazy.json file will be located in the root folder of the project. In this case, it’ll be example-app\.

![](upload://p5kcC6h7NlRxNVoqFt4qCZajktC.png)

Uploading the strings

After all is configured and set, open cmd on your project directory and run localazy.exe upload.

You can learn the different ways to install and run the CLI on the other supported operating systems in the documentation.

![](upload://bPNBmu21luLopzQ8aqkVP050URN.png)

If everything worked perfectly, the strings have been updated, and you’ll now have options to add languages for translation.

![](upload://t0ZtNJ84gPknf0msjPWQNp4eNt5.png)

I’ve added, for example, Portuguese, Spanish, and Czech as the languages I want to translate the project to. Some languages might be already translated by ShareTM technology. Adding one of these languages will show you a review button to approve the suggested phrases. If you add a language that doesn’t have any suggestions, you can start translating immediately with the help of classic machine translations.

![](upload://pPaijIBAjNZdlWPoMVVoZa999DG.png)

All we have to do now is translate or review the strings we uploaded.

![](upload://6TSEGuAxgSFjzMtAWSXyhzoJniq.png)

After we’re all done, it should look like this:

![](upload://9SBYgDkSICN8D6gvbU0LoBrE1C4.png)

Downloading the strings

We can now download our new translated strings back to the project. Let’s open cmd on our project’s root and execute localazy.exe download.

![](upload://nNP2hwcQtNT8Ntcz8DMtTMMgC4e.png)

This will download the strings into our chosen directory /resources/lang and this is how it looks:

![](upload://yP6tQsXb7OtvQi5wcbPkPMgKGcn.png)

🔀 Creating a simple language switcher

The integration is complete, but how can we actually see the results of our project? We will create a language switcher. For this, we’ll have to change some of the code that we wrote so, let’s go back to our web.php file inside example-app\routes and change the code we wrote with the following:


<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
Route::get('/example/{lang}', function ($lang) {
    App::setlocale($lang);
    return view('example');
});

Now we’ll add some code to example.blade.php. The code is four simple anchors that represent the language and change it:


<h1>{{__('example.welcome')}}</h1>
<?php
echo "<h2>" . __('example.php_fun') . "</h2>";
echo __('example.hello') . "<br>";
$x = 30;
$string_1 = __('example.how_old_question') . "<br>";
$string_2 = __('example.how_old_answer', ['years' => $x]) . "<br>";
echo $string_1;
echo $string_2;
?>
 <br>
 <a href="#"> {{__('example.anchor')}} </a>
 <br><br>
 <a href="http://localhost:8000/example/pt"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Flag_of_Portugal.svg/255px-Flag_of_Portugal.svg.png" width="60" height="40" title="Portuguese Flag" ></a>
 <a href="http://localhost:8000/example/cs"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Flag_of_the_Czech_Republic.svg/1280px-Flag_of_the_Czech_Republic.svg.png" width="60" height="40" title="Czech Flag" ></a>
 <a href="http://localhost:8000/example/en"><img src="https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/1200px-Flag_of_the_United_Kingdom.svg.png" width="60" height="40" title="UK Flag" ></a>
 <a href="http://localhost:8000/example/es"><img src="https://www.countryflags.com/wp-content/uploads/spain-flag-png-large.png" width="60" height="40" title="Spanish Flag" ></a>

If we have completed all these steps, we could now access localhost:8000/example/en and this is how it looks:

![](upload://4Ibx7LUtugNUC9bsTftnMHqW4VK.png)

If we click on the Portuguese flag, we’ll have the same page translated to the target language.

![](upload://ueVGyDAaBeMXnpmycmMbaERtff4.png)

🔢 Plurals support

We support Laravel’s plurals basic syntax using the | character; you may distinguish singular and plural forms of a string and use it like we are going to show. For demonstration purposes, we will add echo "<h2>" . trans_choice('example.users', 1). "</h2>"; to our example.blade.php file. The next step is to assign the key with the string 'users' => "There is one user on my website|There are many users on my website" in our example.php file in example-app\resources\lang\en so we can translate it using Localazy. Let’s repeat what we did in the beginning by uploading the new string using cmd with localazy.exe upload.

![](upload://oWgob2RG3oHg6tnf042aEfHN2b3.png)

Translate it and download it using localazy.exe download After the download, we can now try if it works and look at the page at http://localhost:8000/example/en.

![](upload://WOfatge9hYDYH2985e30IQDHjv.png)

This is the singular version and for us to check if the plurals work, we have to change the variable in echo "<h2>" . trans_choice('example.users', 1). "</h2>";, so instead of 1, we can change to 10.

![](upload://lAgXUI4CnoQjh0yXgJ45OS68h7q.png)

We can see that the string changed to “many,” meaning our plurals setup has indeed worked.

![](upload://k8OaW9cPWabqMrbZ4AFRE1RB3AY.png)

In Spanish, for example, it’s also visible that it changes dynamically depending on the number we input.

Pluralization is very complex, and to use it with attributes or with over two plural forms, we need to implement all the plurals manually with Laravel.

✅ Closing words

To finalize our journey, we hope you understood how easy it could be to increase your project’s success with localization. You are only a few clicks away from integrating your projects with Localazy and putting them out for the whole 🌍 to see. If you would like to play around with the prototype, you can check it out on CodeSandbox.

The whole git repository is available on GitHub.

Feel free to join the developer discussion at discuss.localazy.com . Share ideas and feedback, discuss new concepts, and comment on new features of Localazy as we add them ![](upload://7BBDRMxBbSmNSza9xSoFEvGYx4B.png)


This is a companion discussion topic for the original entry at https://localazy.com/blog/laravel-multilingual-i18n-php-localazy