Laravel Inertia React Localization
In this article, I would like to share how to implement localization in a Laravel Inertia React application using a custom service, middleware, and React components. The goal is to detect the user’s preferred language and load corresponding language files to display content in the chosen language.
Step 1: Create BrowserLanguageService
The BrowserLanguageService
is a Laravel service responsible for detecting the user's preferred language based on their browser settings. By utilizing the Request
object, we extract the preferred languages from the browser and return the language code. This service will be used in the middleware to determine the user's language preference.
// app/Services/BrowserLanguageService.php
namespace App\Services;
use Illuminate\Http\Request;
class BrowserLanguageService
{
public function detectLanguage(Request $request)
{
// Get the preferred languages from the browser
$preferredLanguages = $request->getLanguages();
// The first language in the array is usually the preferred language
$browserLanguage = reset($preferredLanguages);
// Use a regular expression to extract only the language code
if (preg_match('/^([a-z]+)/i', $browserLanguage, $matches)) {
$languageCode = strtolower($matches[1]);
return $languageCode;
}
}
}
Step 2: Implement InjectLocaleData Middleware
The InjectLocaleData
middleware is designed to inject localization data into our Inertia application. It uses the BrowserLanguageService
to detect the user's language, loads the corresponding language file, and injects it into the Inertia share function. This ensures that every Inertia page receives the necessary language data, allowing us to display content in the user's preferred language.
// app/Http/Middleware/InjectLocaleData.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Services\BrowserLanguageService;
class InjectLocaleData
{
public function handle(Request $request, Closure $next): Response
{
$browserLanguageService = new BrowserLanguageService();
$languageCode = $browserLanguageService->detectLanguage($request);
// Specify the path to the language JSON files
$localesPath = base_path('app/locales');
$languageFilePath = "{$localesPath}/{$languageCode}.json";
if (file_exists($languageFilePath)) {
$data = json_decode(file_get_contents($languageFilePath), true);
} else {
// Fallback to English if the language file does not exist
$englishFilePath = "{$localesPath}/en.json";
$data = json_decode(file_get_contents($englishFilePath), true);
$languageCode = 'en';
}
// Inject data into Inertia
inertia()->share('localeData', [
'data' => $data,
'languageCode' => $languageCode,
]);
return $next($request);
}
}
Step 3: Register Middleware in Kernel
To make the middleware effective, it needs to be registered in the Laravel application’s kernel. In the Kernel.php
file, we include the InjectLocaleData
middleware in the 'web' middleware group. This ensures that the middleware runs on every web request, enabling the injection of language data into our Inertia pages.
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
// ... other middleware
\App\Http\Middleware\InjectLocaleData::class,
],
];
Step 4: Create Locales Folder and Files
In this step, we create a locales
folder in the app
directory to store language-specific JSON files. Each JSON file represents the content for a specific language (e.g., en.json
for English). These files will be loaded dynamically based on the user's language preference.
Step 5: Use Middleware on a Route
We apply the InjectLocaleData
middleware to a specific route in the routes/web.php
file. This ensures that the middleware is executed when accessing the specified route. The injected language data will then be available in our Inertia pages, allowing us to display content in the user's preferred language.
use App\Http\Middleware\InjectLocaleData;
Route::get('/', function () {
return Inertia::render('Welcome', [
'WelcomeView',
'routeName' => Route::currentRouteName(),
'canLogin' => Route::has('login'),
'canRegister' => Route::has('register'),
'laravelVersion' => Application::VERSION,
'phpVersion' => PHP_VERSION,
]);
})->middleware(InjectLocaleData::class);
Step 6: Inject Data into React Component
Finally, in our Inertia React component (Welcome.js
), we use the usePage
hook to access the injected localeData
from the middleware. This allows us to retrieve the language-specific content and render the Inertia page accordingly. The component is structured to display content based on the user's chosen language, enhancing the user experience with localized information.
// resources/js/Pages/Welcome.js
import { Link, Head, usePage } from "@inertiajs/react";
import WelcomeContents from "./Profile/Partials/WelcomeContents";
import PostView from "./Profile/Partials/PostView";
import WrenchSVG from "@/svg/WrenchSVG";
import RocketSVG from "@/svg/RocketSVG";
import RingSVG from "@/svg/RingSVG";
import AnonSVG from "@/svg/AnonSVG";
export default function Welcome({
auth,
laravelVersion,
phpVersion,
routeName,
}) {
const { localeData } = usePage().props;
// Access the injected data
const { data } = localeData;
const routeMappings = [
{ routeName: "Features", Svg: <WrenchSVG />, dataKey: "features" },
{ routeName: "Plans", Svg: <RocketSVG />, dataKey: "plans" },
{ routeName: "About", Svg: <AnonSVG />, dataKey: "about" },
{ routeName: "Help", Svg: <RingSVG />, dataKey: "help" },
];
const renderPostView = (routeMapping) => {
if (routeName === routeMapping.routeName) {
const { Svg, dataKey } = routeMapping;
return (
<PostView
Svg={Svg}
title={data[dataKey].title}
text={data[dataKey].text}
/>
);
}
return null;
};
return (
<>
...
{routeMappings.map(renderPostView)}
...
</>
);
}
Now you have a complete setup for handling localization in your Laravel Inertia React application. The middleware will detect the user’s preferred language and inject the corresponding language data into your Inertia pages. Feel free to customize the language files and expand the localization features as needed.