Skip to main content

User-Specific Language Dropdown with Country Flags

This guide will walk you through implementing a user-specific language dropdown with real country flags that allows each user to set their own language preference, saves it to the database, and applies it across the entire application.

Overview​

Dropdown button in header

The language dropdown provides:

  • Real country flag icons for each language
  • User-specific language preferences stored in database
  • Automatic language switching across the entire application
  • Persistent language settings across login sessions
  • Clean, responsive design

Prerequisites​

  • Laravel application with user authentication
  • Existing translation files in lang/ directory
  • User table with language field
  • Basic understanding of Laravel middleware and localization

Step 1: Update Language Constants​

First, update your language constants to include country flag codes.

File: config/constants.php​

'langs' => [
'en' => ['full_name' => 'English', 'short_name' => 'English', 'flag_code' => 'us'],
'es' => ['full_name' => 'Spanish - EspaΓ±ol', 'short_name' => 'Spanish', 'flag_code' => 'es'],
'sq' => ['full_name' => 'Albanian - Shqip', 'short_name' => 'Albanian', 'flag_code' => 'al'],
'hi' => ['full_name' => 'Hindi - ΰ€Ήΰ€Ώΰ€‚ΰ€¦ΰ₯€', 'short_name' => 'Hindi', 'flag_code' => 'in'],
'nl' => ['full_name' => 'Dutch', 'short_name' => 'Dutch', 'flag_code' => 'nl'],
'fr' => ['full_name' => 'French - FranΓ§ais', 'short_name' => 'French', 'flag_code' => 'fr'],
'de' => ['full_name' => 'German - Deutsch', 'short_name' => 'German', 'flag_code' => 'de'],
'ar' => ['full_name' => 'Arabic - Ψ§Ω„ΨΉΩŽΨ±ΩŽΨ¨ΩΩŠΩŽΩ‘Ψ©', 'short_name' => 'Arabic', 'flag_code' => 'sa'],
'tr' => ['full_name' => 'Turkish - TΓΌrkΓ§e', 'short_name' => 'Turkish', 'flag_code' => 'tr'],
'id' => ['full_name' => 'Indonesian', 'short_name' => 'Indonesian', 'flag_code' => 'id'],
'ps' => ['full_name' => 'Pashto', 'short_name' => 'Pashto', 'flag_code' => 'af'],
'pt' => ['full_name' => 'Portuguese', 'short_name' => 'Portuguese', 'flag_code' => 'pt'],
'vi' => ['full_name' => 'Vietnamese', 'short_name' => 'Vietnamese', 'flag_code' => 'vn'],
'ce' => ['full_name' => 'Chinese', 'short_name' => 'Chinese', 'flag_code' => 'cn'],
'ro' => ['full_name' => 'Romanian', 'short_name' => 'Romanian', 'flag_code' => 'ro'],
'lo' => ['full_name' => 'Lao', 'short_name' => 'Lao', 'flag_code' => 'la'],
'bn' => ['full_name' => 'Bengali', 'short_name' => 'Bengali', 'flag_code' => 'bd'],
],

Step 2: Add Flag Icons CSS​

Add the Flag Icons CSS library to your layout.

File: resources/views/layouts/partials/css.blade.php​

<!-- Flag Icons CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flag-icons/7.2.3/css/flag-icons.min.css" integrity="sha512-bZBu2H0+FGFz/stDN/L0k8J0G8qVsAL0ht1qg5kTwtAheiXwiRKyCq1frwfbSFSJN3jooR5kauE0YjtPzhZtJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<style>
.fi {
width: 1.2em;
height: 0.9em;
border-radius: 0.125rem;
display: inline-block;
vertical-align: middle;
}
</style>

Step 3: Create User Locale Middleware​

Create middleware to automatically set the application locale based on the authenticated user's language preference.

Generate Middleware​

php artisan make:middleware SetUserLocale

File: app/Http/Middleware/SetUserLocale.php​

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\App;
use Carbon\Carbon; // Add this import

class SetUserLocale
{
public function handle(Request $request, Closure $next)
{
// Check if user is authenticated
if (Auth::check()) {
$user = Auth::user();

// Get user's language preference, default to 'en' if not set
$userLanguage = $user->language ?? 'en';

// Validate that the language exists in available languages
$availableLanguages = array_keys(config('constants.langs', []));
if (in_array($userLanguage, $availableLanguages)) {
// Set application locale for UI translations
App::setLocale($userLanguage);

// Set session locale for consistency
session(['locale' => $userLanguage, 'user.language' => $userLanguage]);
}
}

// CRITICAL: Always keep Carbon in English for date operations
// This prevents "Trailing data" errors in charts and date parsing
Carbon::setLocale('en');

return $next($request);
}
}

Step 4: Register Middleware​

Register the middleware in your HTTP Kernel.

File: app/Http/Kernel.php​

protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\SetUserLocale::class, // Add this line
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];

Step 5: Add Controller Method​

Add a method to handle language updates in your user management controller.

File: app/Http/Controllers/ManageUserController.php​

/**
* Update the current user's language preference
*/
public function updateLanguage(Request $request)
{
try {
$user = Auth::user();
$language = $request->input('language');

// Validate language exists in constants
$available_languages = array_keys(config('constants.langs'));
if (!in_array($language, $available_languages)) {
return response()->json(['success' => false, 'message' => 'Invalid language selected'], 400);
}

// Update user language
$user->language = $language;
$user->save();

// Update session locale for UI translations
app()->setLocale($language);
session(['locale' => $language, 'user.language' => $language]);

// Keep Carbon in English for consistent date operations
\Carbon\Carbon::setLocale('en');

return response()->json(['success' => true, 'message' => 'Language updated successfully']);
} catch (\Exception $e) {
\Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage());

return response()->json(['success' => false, 'message' => 'Failed to update language'], 500);
}
}

Step 6: Add Route​

Add a route for the language update endpoint.

File: routes/web.php​

Route::post('/users/update-language', [ManageUserController::class, 'updateLanguage'])->name('users.update-language');

Step 7: Update Login Controller​

Ensure the user's language is set when they log in.

File: app/Http/Controllers/Auth/LoginController.php​

Add this to the authenticated method:

protected function authenticated(Request $request, $user)
{
// ... existing code ...

// Set user's language preference
if (!empty($user->language)) {
$availableLanguages = array_keys(config('constants.langs', []));
if (in_array($user->language, $availableLanguages)) {
// Set locale for UI translations
app()->setLocale($user->language);
session(['locale' => $user->language, 'user.language' => $user->language]);

// Keep Carbon in English for date operations
\Carbon\Carbon::setLocale('en');
}
}

// ... rest of existing code ...
}

Step 8: Create Language Dropdown​

Add the language dropdown to your header.

File: resources/views/layouts/partials/header.blade.php​

{{-- Language Dropdown --}}
<details class="tw-dw-dropdown tw-relative tw-inline-block tw-text-left">
<summary
class="tw-inline-flex tw-transition-all tw-ring-1 tw-ring-white/10 hover:tw-text-white tw-cursor-pointer tw-duration-200 tw-bg-primary-800 hover:tw-bg-primary-700 tw-py-1.5 tw-px-3 tw-rounded-lg tw-items-center tw-justify-center tw-text-sm tw-font-medium tw-text-white tw-gap-2">
<span class="fi fi-{{ config('constants.langs')[Auth::user()->language]['flag_code'] ?? 'us' }} tw-text-sm"></span>
<span class="tw-hidden md:tw-block">{{ config('constants.langs')[Auth::user()->language]['short_name'] ?? 'English' }}</span>
</summary>
<ul class="tw-p-2 tw-w-56 tw-absolute tw-right-0 tw-z-10 tw-mt-2 tw-origin-top-right tw-bg-white tw-rounded-lg tw-shadow-lg tw-ring-1 tw-ring-gray-200 focus:tw-outline-none"
role="menu" tabindex="-1">
@foreach (config('constants.langs') as $key => $val)
<li>
<a href="javascript:void(0)"
class="change_user_language tw-flex tw-items-center tw-gap-3 tw-px-3 tw-py-2 tw-text-sm tw-font-medium tw-text-gray-600 tw-transition-all tw-duration-200 tw-rounded-lg hover:tw-text-gray-900 hover:tw-bg-gray-100 @if(Auth::user()->language == $key) tw-bg-gray-100 tw-text-gray-900 @endif"
data-language="{{ $key }}"
role="menuitem" tabindex="-1">
<span class="fi fi-{{ $val['flag_code'] ?? 'un' }} tw-text-sm"></span>
<span class="tw-flex-1">{{ $val['full_name'] }}</span>
@if(Auth::user()->language == $key)
<svg class="tw-w-4 tw-h-4" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
@endif
</a>
</li>
@endforeach
</ul>
</details>

Step 9: Add JavaScript Handler​

Add JavaScript to handle the language change functionality.

File: resources/views/layouts/partials/javascripts.blade.php​

<script>
$(document).ready(function() {
// Handle language change
$(document).on('click', '.change_user_language', function(e) {
e.preventDefault();

var language = $(this).data('language');

$.ajax({
url: '{{ route("users.update-language") }}',
type: 'POST',
data: {
language: language,
_token: '{{ csrf_token() }}'
},
success: function(response) {
if (response.success) {
// Reload the page to apply the new language
window.location.reload();
} else {
toastr.error(response.message || 'Failed to update language');
}
},
error: function(xhr, status, error) {
toastr.error('Failed to update language');
}
});
});
});
</script>

Step 10: Clear Caches​

Clear your application caches to ensure all changes take effect:

php artisan config:cache
php artisan view:clear
php artisan route:clear

Testing​

  1. Login to your application
  2. Click the language dropdown in the header
  3. Select a different language
  4. Verify the page reloads in the new language
  5. Check that the language preference persists after logout/login

Customization​

Adding New Languages​

  1. Add language files to lang/ directory
  2. Add JavaScript language files to public/js/lang/
  3. Update config/constants.php with new language entry
  4. Include appropriate flag code

Styling​

Modify the CSS classes in the header template to match your application's design system.

Flag Sources​

The implementation uses the Flag Icons CSS library. You can also use:

  • Local flag images
  • Different flag icon libraries
  • Custom SVG flags

Troubleshooting​

Language Not Changing​

  • Check middleware is registered correctly
  • Verify language files exist
  • Ensure session is working properly

Flags Not Displaying​

  • Verify Flag Icons CSS is loaded
  • Check flag codes match the library format
  • Ensure internet connection for CDN

Database Errors​

  • Verify users table has language column
  • Check column type allows sufficient length
  • Ensure database permissions are correct

Conclusion​

You now have a fully functional user-specific language dropdown with country flags that:

  • Allows each user to set their preferred language
  • Saves preferences to the database
  • Automatically applies language across the application
  • Uses beautiful country flag icons
  • Provides a professional, responsive interface

The implementation is scalable and can easily accommodate additional languages as your application grows.

πŸ’› Support this project

Premium Login