syriable/laravel-localizer
Syriable Localizer is a modern extraction engine for Laravel 13 that scans Blade, PHP, Vue, JS/TS, Livewire and Inertia files to discover and normalize translatable strings, returning typed immutable DTOs via a stable, contracts-driven API.
Installation:
composer require syriable/laravel-localizer
php artisan vendor:publish --provider="Syriable\Localizer\LocalizerServiceProvider" --tag="localizer-config"
config/localizer.php) and migration for tracking extracted strings.Run Extraction:
php artisan localizer:extract
resources/ and app/ by default.resources/lang/ with normalized keys (e.g., {{ __('welcome') }} → welcome).First Use Case:
resources/views/welcome.blade.php):
<h1>{{ __('messages.welcome', ['name' => $name]) }}</h1>
resources/lang/en/messages.php:
return [
'welcome' => 'Welcome, :name!',
];
config/localizer.php – Define paths, ignored files, and key normalization rules.localizer:extract – Core extraction command.localizer:scan – Dry-run to preview extracted strings.localizer:stats – Show extraction coverage.database/migrations/ for the localizer_strings table (tracks extraction history).CI/CD Pipeline:
phpunit.xml or GitHub Actions to run extraction pre-commit or pre-merge:
- name: Extract translations
run: php artisan localizer:extract --force
--force to overwrite existing files (caution: review changes first).Livewire/Inertia Projects:
.vue files (e.g., resources/js/Pages/):
<template>
<h1>{{ $t('messages.hello') }}</h1>
</template>
$t (Vue I18n) and __() (Laravel) patterns automatically.Dynamic Keys:
{{ __('user.'.$user->type) }}) by:
key_normalization in localizer.php:
'key_normalization' => [
'strtolower',
'kebab_case',
],
--normalize flag:
php artisan localizer:extract --normalize=snake_case
Partial Extraction:
php artisan localizer:extract resources/views/auth --output=lang/custom
ignored_paths in config:
'ignored_paths' => [
'resources/views/emails/*',
],
Custom Directives:
// app/Providers/AppServiceProvider.php
Blade::directive('localize', function ($expression) {
return "<?php echo __('{$expression}'); ?>";
});
@localize('key').JavaScript/TypeScript:
i18next or vue-i18n patterns:
// resources/js/app.js
i18n.t('validation.required');
js_patterns in localizer.php:
'js_patterns' => [
'i18n.t',
't',
'$t',
],
Livewire Component Strings:
public function mount() {
$this->title = __('dashboard.title');
}
__() calls in PHP classes within app/Http/Livewire/.Post-Extraction Hooks:
localizer.extracted event to process extracted strings:
// app/Providers/EventServiceProvider.php
protected $listen = [
'localizer.extracted' => [
\App\Listeners\ProcessTranslations::class,
],
];
Key Collisions:
welcome in multiple files) may overwrite translations.--unique-keys to append namespaces:
php artisan localizer:extract --unique-keys=path
Outputs keys like views.welcome.welcome.Ignored Patterns:
patterns in config:
'patterns' => [
'__\(''(.+?)''\)', // Default Laravel
't\(''(.+?)''\)', // Vue I18n
'{{__\s*\((.+?)\)}}', // Blade with whitespace
],
Performance:
--cache flag.--parallel for multi-core processing (if supported in future versions).Livewire/Inertia Edge Cases:
$this->messages['key']) may not extract.ignored_paths or use --include to target specific files.Dry-Run Mode:
php artisan localizer:scan --verbose
Verbose Output:
php artisan localizer:extract --verbose
Database Tracking:
localizer_strings table to audit extraction history:
SELECT file_path, key, extracted_at
FROM localizer_strings
WHERE updated_at > NOW() - INTERVAL 1 DAY;
Normalization Strategies:
kebab_case for consistency with Laravel’s conventions:
'key_normalization' => ['kebab_case'],
user.first_name → user.first-name.Exclude Tests:
'ignored_paths' => [
'tests/*',
'resources/views/vendor/*',
],
Custom Output Paths:
resources/lang/:
php artisan localizer:extract --output=lang/custom
Integration with Crowdin/Lingohub:
localizer:stats command to generate reports for translation platforms:
php artisan localizer:stats --format=json > stats.json
TypeScript Support:
ts_patterns for TypeScript files:
'ts_patterns' => [
't\`(.+?)\`', // Template literals
'$t\(''(.+?)''\)',
],
Backup Before Force Extraction:
resources/lang/ before running --force:
cp -r resources/lang resources/lang.bak
How can I help you explore Laravel packages today?