Skip to content

lang:publish Command Publishes Files to ./lang, But Laravel Only Loads Translations from resources/lang #58832

@cirlmcesc

Description

@cirlmcesc

🐛 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.

  • Expected Behavior:

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:

  1. The Application::useLangPath() logic is not applied by default in Laravel 12, or
  2. 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

  1. Fix the default lang path so Laravel actually loads from ./lang in new applications.
  2. OR, revert lang:publish to publish to resources/lang if that’s still the effective path.
  3. Update documentation to reflect actual behavior.
  4. Add a runtime check:
    if (is_dir(base_path('lang')) && !is_dir(resource_path('lang'))) {
        app()->useLangPath(base_path('lang'));
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions