Implementing Multi-Language Support in Laravel Project Without lang/*.json Files
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Implementing Multi-Language Support in Laravel Project Without lang/*.json Files
As a senior developer working with Laravel, you are familiar with the standard approach to localization—using the lang directory and .json files. While simple for small projects, this method can become cumbersome when dealing with complex, dynamic content or when scaling up internationalization (i18n) features. If your requirement is to achieve multi-language support dynamically, without relying on static file structures like lang/*.json, you need a more database-centric and flexible approach.
This guide will walk you through an alternative method for implementing robust, dynamic localization in Laravel, focusing on best practices that align with the power of the Laravel ecosystem.
The Shift: From Files to Database for Localization
The traditional file-based system is simple but suffers from poor dynamism. Adding a new language requires modifying files and potentially recompiling or redeploying assets. To meet your requirement for dynamic management—where you can add or change languages without touching code—the solution lies in storing translations directly in the database.
This approach treats translations as data, which allows them to be managed via Eloquent models, offering superior flexibility and scalability. This methodology aligns perfectly with the principles of clean architecture that Laravel promotes, allowing for highly decoupled components.
Implementing Database-Driven Localization
Instead of static files, we will create a dedicated database structure to hold all translation strings. This involves three main steps: defining the necessary tables, creating migrations, and setting up the Eloquent relationships.
Step 1: Database Structure (Migrations)
We need at least two core models: one for managing languages and another for storing the actual translations.
First, create a migration to set up the language structure:
// database/migrations/..._create_languages_table.php
Schema::create('languages', function (Blueprint $table) {
$table->id();
$table->string('code')->unique(); // e.g., 'en', 'fr', 'es'
$table->string('name');
$table->timestamps();
});
Schema::create('translations', function (Blueprint $table) {
$table->id();
$table->foreignId('language_id')->constrained()->onDelete('cascade');
$table->string('key'); // The unique identifier for the text, e.g., 'welcome_message'
$table->text('value'); // The translated content
$table->timestamps();
});
After running the migration, you can dynamically add languages by inserting records into the languages table, fulfilling your requirement for dynamic management.
Step 2: Eloquent Models and Relationships
Define your Eloquent models to interact with this data. The key is setting up a many-to-many or one-to-many relationship between languages and their respective translations. This structure allows you to easily fetch all translations for a specific language code.
For instance, in your Translation model, you would define the relationship:
// app/Models/Translation.php
class Translation extends Model
{
protected $fillable = ['language_id', 'key', 'value'];
public function language()
{
return $this->belongsTo(Language::class);
}
}
Step 3: Dynamic Retrieval in Controllers
When a request comes in, you can now dynamically fetch the correct translation based on the requested locale. This logic lives entirely within your application layer, completely decoupled from static files.
// Example Controller Logic Snippet
public function getLocalizedText($key, $locale)
{
$translation = Translation::where('key', $key)
->where('language_id', Language::where('code', $locale)->value('id'))
->first();
if ($translation) {
return $translation->value;
}
// Fallback to default language if translation is missing
return __('default_' . $key);
}
Conclusion: Scalability Through Data
By moving localization data from static files into a relational database, you achieve a system that is inherently more dynamic and scalable. This approach eliminates the need for manual file management when adding new languages or updating strings, offering a significant advantage in large-scale applications. While Laravel provides excellent tools for building robust systems, leveraging these capabilities to manage complex data structures—as seen in how powerful the underlying architecture of the Laravel Company is—allows you to build truly dynamic features that adapt to changing requirements. This database-driven method provides the flexibility you need while adhering to modern development practices.