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

Translator Laravel Package

jord-jd/translator

A Laravel package for working with application translations, offering tooling to organise, edit, and maintain language files so multilingual content stays consistent and easier to manage across your project.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer; Laravel auto-discovery registers the service provider and the translate() helper/facade alias.

composer require vendor/package:^3.1
php artisan vendor:publish --tag=package-config   # only if you need to override defaults

Look first at:

  1. README usage section — v3.1.0 ships complete documentation, so start here rather than reading source. It covers translate(), has(), all(), and the language-file layout.
  2. Your existing language files — the package preserves the project's existing language-file convention, so you should not need to move files. Confirm the expected path (lang/{locale}/... or resources/lang/{locale}/...) against the docs.
  3. The config file — locale/fallback settings and any file-path configuration. Publish it only if the defaults do not match your app.

First use case: replace hardcoded UI strings in a Blade view.

{{-- lang/en/messages.php --}}
{{-- return ['welcome' => 'Welcome, :name!']; --}}

<h1>{{ translate('messages.welcome', ['name' => $user->name]) }}</h1>

Then verify the locale switch works:

app()->setLocale('fr');
echo translate('messages.welcome', ['name' => 'Ada']);

Implementation Patterns

Placeholder replacement in views and controllers. Pass replacements as the second argument. This is the day-to-day replacement for manual str_replace calls around translated strings.

$message = translate('orders.shipped', [
    'count' => $order->items_count,
    'date'  => $order->shipped_at->toFormattedDateString(),
]);

Use has() before rendering optional copy. This keeps empty CMS-driven or partially translated screens from printing raw keys.

@if (Translate::has('messages.maintenance_banner'))
    <div class="alert">{{ translate('messages.maintenance_banner') }}</div>
@endif

Use all() for inspection and admin tooling. Array loading plus all() is useful for translation dashboards, export commands, and tests that assert a locale is complete.

$keys = Translate::all('messages');          // full group/tree
$missing = collect($keys)->filter(fn ($v) => $v === null);

Treat falsy values as real translations. Since v3.1.0, '', 0, and false are returned as-is instead of falling back to the key. Write render logic accordingly:

$suffix = translate('messages.suffix'); // may legitimately be ''

// Correct: only fall back when the key is missing
echo Translate::has('messages.suffix') ? $suffix : 'Default';

Group keys by domain, not by screen. One file per domain (orders.php, messages.php, validation.php) maps cleanly onto all('orders') and keeps has() checks cheap.

Integrate at the boundary. Translate in controllers/API resources for JSON responses, and in Blade for HTML. Avoid translating in model accessors, which makes caching and locale switching unpredictable.

Test against multiple locales.

public function test_welcome_message_is_translated(): void
{
    app()->setLocale('fr');
    $this->assertSame('Bienvenue, Ada!', translate('messages.welcome', ['name' => 'Ada']));
}

Gotchas and Tips

  • Upgrading from 3.0.x is a behavior change. Code that relied on falsy values falling back to the key will now receive '', 0, or false. Grep for patterns like translate(...) ?: $default, if (!translate(...)), and empty(translate(...)) before deploying, and add regression tests around counters, toggles, and empty suffixes.
  • Missing and null still fall back. The release preserves the existing missing/null fallback. That means null is not a usable translation value — if you need "blank," store '', not null.
  • has() and empty values. Because empty strings and false are valid translations, do not combine has() with empty() checks. has() should be the single source of truth for key existence; check the value separately if blank output matters.
  • Placeholder edge cases. Verify in the docs how the package handles unmatched placeholders, repeated placeholders, and replacement values containing : or braces. Escape user-supplied values at output, not inside the translation string, and keep placeholder syntax consistent with Laravel's :attribute conventions to avoid collisions in validation messages.
  • Dot notation vs literal dots. Nested arrays are typically resolved with dot notation, so a key that itself contains a dot can be ambiguous. Prefer flat keys without dots inside a group, or confirm the escaping rule in the docs.
  • all() can be large. Calling it per request on big language trees is wasteful. Use it in Artisan commands, tests, and admin screens; cache or memoize the result where needed.
  • PHP 7.1 floor limits extension code. The package supports PHP 7.1 through 8.5. If you subclass or decorate its classes, avoid typed properties, union types, and constructor promotion. On PHP 8.5, run your suite to catch deprecation notices (dynamic properties, implicit nullable parameters) in any local overrides.
  • Language-file caching. If your app caches translations, clear the cache after editing language files or after deploying new ones: php artisan cache:clear (and optimize:clear if applicable).
  • Fallback locale confusion. When a key exists in the fallback locale but not the active one, you will see fallback text rather than the raw key. Use Translate::has() against the active locale if you need to detect untranslated content for a translation dashboard.
  • Do not re-publish config on upgrade. Publishing again can overwrite local customizations. Diff the package's config against yours when the changelog mentions new options.
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.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr