🐛 Bug Report
- Laravel Version: 12.x (e.g., 12.0.3)
- PHP Version: 8.3
- Database Driver & Version: N/A
- Description:
The php artisan lang:publish command publishes language files to the project root directory (./lang), but Laravel does not load translations from this directory at all. Instead, it only reads from resources/lang, even in a fresh Laravel 12 application.
This makes the lang:publish command misleading and effectively broken, because:
-
The published files in ./lang have no effect on translation output.
-
Developers assume ./lang is the new standard (per Laravel 9+ docs), but it’s ignored silently.
-
There is no error, warning, or documentation explaining that ./lang is not being used.
-
Steps To Reproduce:
# 1. Create a brand new Laravel 12 project
laravel new test-lang-issue
cd test-lang-issue
# 2. Publish language files (creates ./lang)
php artisan lang:publish
# Confirm files exist in root
ls ./lang/en/auth.php # ✅ exists
# Ensure resources/lang does NOT exist
ls resources/lang # ❌ No such file or directory
# 3. Test translation in Tinker
php artisan tinker
>>> __('auth.failed')
Expected: Returns the string from ./lang/en/auth.php (e.g., "These credentials do not match our records.")
Actual: Throws an error or returns the key itself ("auth.failed"), indicating no translation was found.
💡 In many cases, it falls back to the key because resources/lang doesn’t exist and ./lang is not loaded.
Now, manually move the folder:
mv lang resources/
php artisan tinker
>>> __('auth.failed') // ✅ Now it works!
This proves Laravel only reads from resources/lang, completely ignoring ./lang.
Since Laravel 9+ announced that the language directory has moved to the project root (./lang), the framework should:
-
Load translations from ./lang by default, OR
-
The lang:publish command should publish to resources/lang if that’s still the active path.
-
Actual Behavior:
-
lang:publish writes to ./lang
-
But translation loader ignores ./lang entirely
-
Only resources/lang is respected
-
No indication of why translations are missing
-
Additional Context:
This suggests that either:
- The
Application::useLangPath() logic is not applied by default in Laravel 12, or
- The service provider that sets the lang path is not registering correctly in new apps.
The Laravel 12 Localization documentation states:
“Laravel’s default language files are now published to the lang directory in your application’s root.”
But in practice, this is not true — the files are published there, but not loaded from there.
✅ Suggested Fix
- Fix the default lang path so Laravel actually loads from
./lang in new applications.
- OR, revert
lang:publish to publish to resources/lang if that’s still the effective path.
- Update documentation to reflect actual behavior.
- Add a runtime check:
if (is_dir(base_path('lang')) && !is_dir(resource_path('lang'))) {
app()->useLangPath(base_path('lang'));
}
🐛 Bug Report
The
php artisan lang:publishcommand publishes language files to the project root directory (./lang), but Laravel does not load translations from this directory at all. Instead, it only reads fromresources/lang, even in a fresh Laravel 12 application.This makes the
lang:publishcommand misleading and effectively broken, because:The published files in
./langhave no effect on translation output.Developers assume
./langis the new standard (per Laravel 9+ docs), but it’s ignored silently.There is no error, warning, or documentation explaining that
./langis not being used.Steps To Reproduce:
Expected: Returns the string from
./lang/en/auth.php(e.g., "These credentials do not match our records.")Actual: Throws an error or returns the key itself (
"auth.failed"), indicating no translation was found.Now, manually move the folder:
This proves Laravel only reads from
resources/lang, completely ignoring./lang.Since Laravel 9+ announced that the language directory has moved to the project root (
./lang), the framework should:Load translations from
./langby default, ORThe
lang:publishcommand should publish toresources/langif that’s still the active path.Actual Behavior:
lang:publishwrites to./langBut translation loader ignores
./langentirelyOnly
resources/langis respectedNo indication of why translations are missing
Additional Context:
This suggests that either:
Application::useLangPath()logic is not applied by default in Laravel 12, orThe Laravel 12 Localization documentation states:
But in practice, this is not true — the files are published there, but not loaded from there.
✅ Suggested Fix
./langin new applications.lang:publishto publish toresources/langif that’s still the effective path.