Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel4 Lang Laravel Package

caouecs/laravel4-lang

caouecs/laravel4-lang provides ready-to-use Laravel 4 language files for validation, authentication, pagination, reminders, and other framework messages. With translations for dozens of locales, it helps you add multilingual support quickly by copying the files into your app.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a translations repository, not a runtime package. It ships ~128 locale folders of plain PHP/JSON arrays that Laravel's translator already knows how to consume. There is no service provider, no facade, no artisan command — the "integration" is copying files into your lang/ directory.

Minimal steps (Laravel 9+):

composer require caouecs/laravel-lang   # repo name is laravel4-lang, composer name differs
php artisan lang:publish                # Laravel 9/10/11: creates lang/en as a baseline
cp -R vendor/caouecs/laravel-lang/src/{fr,de,pt_BR} lang/

Then in .env:

APP_LOCALE=fr
APP_FALLBACK_LOCALE=en

And confirm in config/app.php that locale, fallback_locale, and faker_locale are read from env (they are by default). On Laravel ≤ 8 the destination is resources/lang/ instead of lang/.

Where to look first: open lang/fr/validation.php and scroll to the bottom. The attributes array (field-name translations) and the custom array (per-rule-per-field overrides) are the two keys you'll touch most. Then check auth.php and passwords.php — these feed Breeze/Fortify/UI login screens for free.

First use case: you have a POST /contact endpoint with a FormRequest and want French validation errors. Copy fr/, set APP_LOCALE=fr, and every :attribute placeholder now resolves against validation.attributes — assuming your input names match (email, password, name, …). If they don't, that's the first thing you'll override.

Implementation Patterns

Copy only what you support, and script it. Vendoring 128 locales bloats the repo and makes diffs unreadable. Keep a whitelist and a one-liner in your deploy/onboarding docs:

# scripts/sync-lang.sh
for l in en fr de pt_BR; do
  rm -rf lang/$l
  cp -R vendor/caouecs/laravel-lang/src/$l lang/$l
done

Run it after every composer update, then git diff lang/ — that diff is your changelog for upstream wording changes.

Per-request locale via middleware. Don't call App::setLocale() scattered around controllers. One middleware, ordered early in the web group:

public function handle(Request $request, Closure $next)
{
    $locale = $request->session()->get('locale')
        ?? $request->getPreferredLanguage(config('app.available_locales'));

    if (! in_array($locale, config('app.available_locales'), true)) {
        $locale = config('app.fallback_locale');
    }

    app()->setLocale($locale);
    return $next($request);
}

Locale-prefixed routes for SEO/durable URLs (/fr/contact). Bind the segment in RouteServiceProvider or a Route::pattern('locale', 'en|fr|de') so an unknown prefix 404s instead of silently falling back.

Overriding attributes for domain vocabulary. If your field is company_vat_id, English validation.php will render it literally. Add to your own lang/fr/validation.php:

'attributes' => [
    'company_vat_id' => 'numéro de TVA',
    'email'          => 'adresse e-mail',
],

Two options: edit the copied file (simple, but you must re-apply after sync) or keep overrides in a separate file loaded at boot — see Gotchas.

Per-field, per-rule overrides belong in the FormRequest, not in the lang file, when they're context-specific:

public function messages(): array
{
    return [
        'email.required'     => __('validation.custom.email.required'),
        'password.min'       => __('validation.custom.password.min', ['min' => 12]),
    ];
}

Custom rules and Validator::extend should return a translation key, never a sentence:

Validator::extend('vat', fn ($attr, $value) => Vat::isValid($value));
Validator::replacer('vat', fn ($message, $attr, $rule, $params) =>
    str_replace(':attribute', $attr, $message));

Then 'vat' => 'The :attribute is not a valid VAT number.' goes into the rules array of every locale you ship — and stays translatable by whoever maintains the language folders.

JSON strings vs PHP files. __('validation.required') reads lang/fr/validation.php; __('Save changes') reads lang/fr.json. Laravel's own validation/auth/pagination keys live in PHP files, so don't put those strings in JSON — you'll get the raw key back. Conversely, don't try to model app UI copy as PHP arrays; use the JSON file per locale.

Testing. Pin the locale explicitly; never rely on the ambient default in tests that assert on message text:

$this->withSession(['locale' => 'fr'])
     ->post('/contact', [])
     ->assertSessionHasErrors(['email' => __('validation.required', ['attribute' => 'adresse e-mail'], 'fr')]);

Adjacent packages worth knowing. The same ecosystem publishes laravel-lang/attributes (translated field names), laravel-lang/http-statuses, and laravel-lang/actions. For Laravel 10/11 the maintained entrypoint is laravel-lang/common, which gives you php artisan lang:add {locale} and lang:update instead of manual cp.

Gotchas and Tips

This repo is legacy. caouecs/laravel4-lang is the historical name; the project moved to the Laravel-Lang GitHub org and the modern workflow is laravel-lang/common (php artisan lang:add fr). If you're on Laravel 10+, start there and treat this package as the fallback for older versions. Check the compatibility table in the README before composer require — versions are pinned per Laravel major, and a mismatched version will ship a validation.php missing rules your app uses.

Laravel 9 moved the directory. resources/lang/ → lang/ at the project root ($app->langPath()). Copying into the old path on Laravel 9+ silently does nothing and every message falls back.

Locale identifiers are exact and case-sensitive. pt_BR, zh_CN, sr_Latn — the folder name must byte-match app()->getLocale(). On Linux, pt-br ≠ pt_BR. The hyphen/underscore distinction also matters for Accept-Language negotiation, so normalize incoming headers before comparing.

Never edit vendor/. Whatever you change there disappears on the next composer update. Keep overrides in lang/{locale}/ and re-sync from vendor, or load them at boot so upstream files stay pristine:

// AppServiceProvider::boot()
Lang::addLines([
    'validation.attributes.company_vat_id' => 'numéro de TVA',
], 'fr');

addLines supports dot-notation keys in current Laravel, but verify on your version — on older releases it sets a flat key and your override won't be found. A plain lang/fr/validation.php you own is the bulletproof option.

fallback_locale masks missing translations. A missing key in fr renders the en string; developers on English never see the bug. Audit with:

array_diff(array_keys(__('validation', [], 'en')), array_keys(__('validation', [], 'fr')));

validation-inline.php is a separate file. Laravel ≥ 6 uses it for messages that omit the attribute name (e.g. inline validation without a field label). If you only copy validation.php, some paths render English while others render French — copy the whole locale folder.

Plural forms differ per language. Pagination uses :count, validation uses :min/:max/:other, and Slavic/Arabic locales need multiple |-separated variants. Don't test pluralization with 1 only — test 0, 1, 2, 5, and a fractional case if your UI allows it.

Octane and long-running workers cache the translator. After adding a locale during a deploy, workers hold the old loaded set. php artisan optimize:clear in the release hook; config:cache alone won't help because lang files aren't config.

faker_locale is not locale. Factories generating French addresses need APP_FAKER_LOCALE=fr_FR, while your UI locale is fr. Faker uses IETF-style (fr_FR, en_US); Laravel's translation folders use the project's own scheme — do not assume they're interchangeable.

This package does not translate Nova, Cashier, Breeze, or Jetstream UI copy. Those ship their own lang/ folders inside their own packages; the repo description lists them because the ecosystem provides companion translation sets, not because installing this gives you a French Nova. Check vendor/laravel/nova/resources/lang separately.

Extension point if you need dialect variants. Register a namespace and layer it over the base locale:

Lang::addNamespace('site', lang_path('vendor/site'));
// __('site::validation.required')

Useful for regional wording (fr_CA on top of fr) without forking an entire locale folder.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo