Weave Code
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

Laravel Localizer Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require syriable/laravel-localizer
    php artisan vendor:publish --provider="Syriable\Localizer\LocalizerServiceProvider" --tag="localizer-config"
    
    • Publishes default config (config/localizer.php) and migration for tracking extracted strings.
  2. Run Extraction:

    php artisan localizer:extract
    
    • Scans Blade, PHP, Vue, JS/TS, Livewire, and Inertia files in resources/ and app/ by default.
    • Outputs extracted strings to resources/lang/ with normalized keys (e.g., {{ __('welcome') }}welcome).
  3. First Use Case:

    • Translate a Blade file (resources/views/welcome.blade.php):
      <h1>{{ __('messages.welcome', ['name' => $name]) }}</h1>
      
    • After extraction, add translations to resources/lang/en/messages.php:
      return [
          'welcome' => 'Welcome, :name!',
      ];
      

Where to Look First

  • Config: config/localizer.php – Define paths, ignored files, and key normalization rules.
  • Artisan Commands:
    • localizer:extract – Core extraction command.
    • localizer:scan – Dry-run to preview extracted strings.
    • localizer:stats – Show extraction coverage.
  • Migrations: Check database/migrations/ for the localizer_strings table (tracks extraction history).

Implementation Patterns

Workflow Integration

  1. CI/CD Pipeline:

    • Add to phpunit.xml or GitHub Actions to run extraction pre-commit or pre-merge:
      - name: Extract translations
        run: php artisan localizer:extract --force
      
    • Use --force to overwrite existing files (caution: review changes first).
  2. Livewire/Inertia Projects:

    • Extract strings from .vue files (e.g., resources/js/Pages/):
      <template>
        <h1>{{ $t('messages.hello') }}</h1>
      </template>
      
    • Localizer detects $t (Vue I18n) and __() (Laravel) patterns automatically.
  3. Dynamic Keys:

    • Handle dynamic keys (e.g., {{ __('user.'.$user->type) }}) by:
      • Configuring key_normalization in localizer.php:
        'key_normalization' => [
            'strtolower',
            'kebab_case',
        ],
        
      • Or use --normalize flag:
        php artisan localizer:extract --normalize=snake_case
        
  4. Partial Extraction:

    • Target specific paths:
      php artisan localizer:extract resources/views/auth --output=lang/custom
      
    • Exclude files with ignored_paths in config:
      'ignored_paths' => [
          'resources/views/emails/*',
      ],
      

Advanced Patterns

  1. Custom Directives:

    • Extend Blade directives for localization:
      // app/Providers/AppServiceProvider.php
      Blade::directive('localize', function ($expression) {
          return "<?php echo __('{$expression}'); ?>";
      });
      
    • Localizer will extract strings wrapped in @localize('key').
  2. JavaScript/TypeScript:

    • Use i18next or vue-i18n patterns:
      // resources/js/app.js
      i18n.t('validation.required');
      
    • Configure js_patterns in localizer.php:
      'js_patterns' => [
          'i18n.t',
          't',
          '$t',
      ],
      
  3. Livewire Component Strings:

    • Extract strings from Livewire properties/methods:
      public function mount() {
          $this->title = __('dashboard.title');
      }
      
    • Localizer detects __() calls in PHP classes within app/Http/Livewire/.
  4. Post-Extraction Hooks:

    • Listen to localizer.extracted event to process extracted strings:
      // app/Providers/EventServiceProvider.php
      protected $listen = [
          'localizer.extracted' => [
              \App\Listeners\ProcessTranslations::class,
          ],
      ];
      

Gotchas and Tips

Pitfalls

  1. Key Collisions:

    • Issue: Duplicate keys (e.g., welcome in multiple files) may overwrite translations.
    • Fix: Use --unique-keys to append namespaces:
      php artisan localizer:extract --unique-keys=path
      
      Outputs keys like views.welcome.welcome.
  2. Ignored Patterns:

    • Issue: Localizer may miss strings in custom templates (e.g., Markdown, handlebars).
    • Fix: Extend patterns in config:
      'patterns' => [
          '__\(''(.+?)''\)', // Default Laravel
          't\(''(.+?)''\)',  // Vue I18n
          '{{__\s*\((.+?)\)}}', // Blade with whitespace
      ],
      
  3. Performance:

    • Issue: Large projects slow down extraction.
    • Fix:
      • Cache results with --cache flag.
      • Use --parallel for multi-core processing (if supported in future versions).
  4. Livewire/Inertia Edge Cases:

    • Issue: Strings in dynamic Livewire properties (e.g., $this->messages['key']) may not extract.
    • Fix: Manually add to ignored_paths or use --include to target specific files.

Debugging

  1. Dry-Run Mode:

    php artisan localizer:scan --verbose
    
    • Shows extracted strings without writing files.
  2. Verbose Output:

    php artisan localizer:extract --verbose
    
    • Logs file-by-file processing and skipped items.
  3. Database Tracking:

    • Query the localizer_strings table to audit extraction history:
      SELECT file_path, key, extracted_at
      FROM localizer_strings
      WHERE updated_at > NOW() - INTERVAL 1 DAY;
      

Tips

  1. Normalization Strategies:

    • Use kebab_case for consistency with Laravel’s conventions:
      'key_normalization' => ['kebab_case'],
      
    • Example: user.first_nameuser.first-name.
  2. Exclude Tests:

    • Ignore test files to avoid noise:
      'ignored_paths' => [
          'tests/*',
          'resources/views/vendor/*',
      ],
      
  3. Custom Output Paths:

    • Override default resources/lang/:
      php artisan localizer:extract --output=lang/custom
      
  4. Integration with Crowdin/Lingohub:

    • Use the localizer:stats command to generate reports for translation platforms:
      php artisan localizer:stats --format=json > stats.json
      
  5. TypeScript Support:

    • Configure ts_patterns for TypeScript files:
      'ts_patterns' => [
          't\`(.+?)\`', // Template literals
          '$t\(''(.+?)''\)',
      ],
      
  6. Backup Before Force Extraction:

    • Always back up resources/lang/ before running --force:
      cp -r resources/lang resources/lang.bak
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity