Overview
Cashify supports multiple languages through Laravel’s built-in localization features. Currently, the application includes full translations for:
English (en) - Default language
Bulgarian (bg) - Bulgarian translations
Configuration
Application Locale Settings
Locale configuration is managed in config/app.php and can be overridden via environment variables:
return [
'locale' => env ( 'APP_LOCALE' , 'en' ),
'fallback_locale' => env ( 'APP_FALLBACK_LOCALE' , 'en' ),
'faker_locale' => env ( 'APP_FAKER_LOCALE' , 'en_US' ),
];
Environment Variables
Set the default locale in your .env file:
APP_LOCALE = en
APP_FALLBACK_LOCALE = en
The default locale for the application. Determines which language is displayed by default.
The fallback locale used when a translation is missing in the current locale.
Language Files
Translation files are stored in the lang/ directory, organized by locale:
lang/
├── en/
│ ├── auth.php
│ ├── pagination.php
│ ├── passwords.php
│ └── validation.php
└── bg/
├── auth.php
├── pagination.php
├── passwords.php
└── validation.php
Authentication Messages
Authentication error messages are localized:
lang/en/auth.php
lang/bg/auth.php
<? php
return [
'failed' => 'These credentials do not match our records.' ,
'password' => 'The provided password is incorrect.' ,
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.' ,
];
Validation Messages
Validation error messages are fully translated:
lang/en/validation.php
lang/bg/validation.php
<? php
return [
'required' => 'The :attribute field is required.' ,
'email' => 'The :attribute must be a valid email address.' ,
'unique' => 'The :attribute has already been taken.' ,
'confirmed' => 'The :attribute confirmation does not match.' ,
// ... more validation rules
];
Password Reset Messages
lang/en/passwords.php
lang/bg/passwords.php
<? php
return [
'reset' => 'Your password has been reset.' ,
'sent' => 'We have emailed your password reset link.' ,
'throttled' => 'Please wait before retrying.' ,
'token' => 'This password reset token is invalid.' ,
'user' => "We can't find a user with that email address." ,
];
lang/en/pagination.php
lang/bg/pagination.php
<? php
return [
'previous' => '« Previous' ,
'next' => 'Next »' ,
];
Runtime Locale Switching
Cashify implements runtime locale switching using session-based storage.
SetLocale Middleware
The SetLocale middleware applies the user’s selected locale:
app/Http/Middleware/SetLocale.php
namespace App\Http\Middleware ;
use Closure ;
use Illuminate\Http\ Request ;
use Symfony\Component\HttpFoundation\ Response ;
class SetLocale
{
/**
* Handle an incoming request.
*/
public function handle ( Request $request , Closure $next ) : Response
{
if ( session () -> has ( 'locale' )) {
app () -> setLocale ( session ( 'locale' ));
}
return $next ( $request );
}
}
Register Middleware
Register the middleware in your application’s middleware stack:
use App\Http\Middleware\ SetLocale ;
return Application :: configure ( basePath : dirname ( __DIR__ ))
-> withMiddleware ( function ( Middleware $middleware ) {
$middleware -> web ( append : [
SetLocale :: class ,
]);
})
-> create ();
Switching Locale
Create a route and controller to switch locales:
Route :: post ( '/locale' , function ( Request $request ) {
$locale = $request -> input ( 'locale' );
if ( in_array ( $locale , [ 'en' , 'bg' ])) {
session ([ 'locale' => $locale ]);
}
return redirect () -> back ();
}) -> name ( 'locale.switch' );
Frontend Language Switcher
Add a language switcher to your layout:
resources/views/components/locale-switcher.blade.php
< form method = "POST" action = " {{ route ('locale.switch') }} " >
@csrf
< select name = "locale" onchange = " this . form . submit ()"
class = "border rounded px-3 py-2" >
< option value = "en" {{ app () -> getLocale () === 'en' ? 'selected' : '' }} >
English
</ option >
< option value = "bg" {{ app () -> getLocale () === 'bg' ? 'selected' : '' }} >
Български
</ option >
</ select >
</ form >
Using Translations in Code
In Blade Templates
Use the __() helper or @lang directive:
<!-- Using the __() helper -->
< h1 > {{ __ ( 'Welcome to Cashify' ) }} </ h1 >
<!-- Using @lang directive -->
< p > @lang ( 'auth.failed' ) </ p >
<!-- With parameters -->
< p > {{ __ ( 'auth.throttle' , [ 'seconds' => 60 ]) }} </ p >
In Controllers
Use the __() helper function:
public function store ( Request $request )
{
// Validation with translated messages happens automatically
$request -> validate ([
'email' => 'required|email' ,
'password' => 'required' ,
]);
// Custom translated flash message
return redirect () -> back () -> with ( 'success' , __ ( 'Profile updated successfully' ));
}
In JavaScript
For frontend translations, you can expose Laravel translations to JavaScript:
< script >
window . translations = @ json ([
'save' => __ ( 'Save' ),
'cancel' => __ ( 'Cancel' ),
'delete_confirm' => __ ( 'Are you sure you want to delete this?' ),
]);
</ script >
Adding a New Language
To add support for a new language:
Create Language Directory
Create a new directory under lang/ with the locale code: mkdir lang/es # For Spanish
Copy Translation Files
Copy the English translation files as a template: cp lang/en/ * .php lang/es/
Translate Messages
Edit each file and translate the messages: return [
'failed' => 'Estas credenciales no coinciden con nuestros registros.' ,
'password' => 'La contraseña proporcionada es incorrecta.' ,
'throttle' => 'Demasiados intentos de inicio de sesión. Por favor intente de nuevo en :seconds segundos.' ,
];
Update Locale Switcher
Add the new language to your locale switcher: < option value = "es" {{ app () -> getLocale () === 'es' ? 'selected' : '' }} >
Español
</ option >
Update Validation
Update your locale validation to include the new language: if ( in_array ( $locale , [ 'en' , 'bg' , 'es' ])) {
session ([ 'locale' => $locale ]);
}
Translation Best Practices
Use Translation Keys
Avoid hardcoding text in your views:
< button > Save Changes </ button >
Organize Translation Files
Group related translations into logical files:
lang/
├── en/
│ ├── auth.php # Authentication messages
│ ├── transactions.php # Transaction-related messages
│ ├── accounts.php # Account-related messages
│ ├── categories.php # Category-related messages
│ └── common.php # Common UI messages
Use Placeholders
Use placeholders for dynamic content:
return [
'created' => 'Transaction created successfully.' ,
'updated' => 'Transaction updated successfully.' ,
'deleted' => 'Transaction deleted successfully.' ,
'amount_format' => 'Amount: :amount :currency' ,
];
Usage:
__ ( 'transactions.amount_format' , [
'amount' => number_format ( $amount , 2 ),
'currency' => 'USD'
])
Pluralization
Laravel supports pluralization in translations:
return [
'count' => '{0} No transactions|{1} One transaction|[2,*] :count transactions' ,
];
Usage:
trans_choice ( 'transactions.count' , $count )
Available Locales
Cashify currently includes:
English (en) Default language with complete translations
Bulgarian (bg) Full Bulgarian translations available
Testing Localization
Test your translations with different locales:
tests/Feature/LocalizationTest.php
use Illuminate\Foundation\Testing\ RefreshDatabase ;
use Tests\ TestCase ;
class LocalizationTest extends TestCase
{
public function test_authentication_messages_are_translated ()
{
app () -> setLocale ( 'bg' );
$response = $this -> post ( '/login' , [
'email' => '[email protected] ' ,
'password' => 'wrong' ,
]);
$response -> assertSessionHasErrors ();
$this -> assertEquals ( 'bg' , app () -> getLocale ());
}
public function test_locale_persists_in_session ()
{
$this -> post ( '/locale' , [ 'locale' => 'bg' ]);
$this -> assertEquals ( 'bg' , session ( 'locale' ));
}
}
Caching Translations
For better performance in production, cache your translations:
# Cache translations
php artisan lang:publish
php artisan optimize
# Clear translation cache
php artisan optimize:clear
Common Translation Strings
Here are commonly used translation strings you may need:
return [
'save' => 'Save' ,
'cancel' => 'Cancel' ,
'delete' => 'Delete' ,
'edit' => 'Edit' ,
'create' => 'Create' ,
'update' => 'Update' ,
'search' => 'Search' ,
'filter' => 'Filter' ,
'actions' => 'Actions' ,
'confirm_delete' => 'Are you sure you want to delete this?' ,
'success' => 'Operation completed successfully.' ,
'error' => 'An error occurred. Please try again.' ,
];
Next Steps
Environment Variables Configure locale-related environment variables
Authentication Localized authentication messages