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 Translation Scanner Laravel Package

nativecodein/laravel-translation-scanner

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps
1. **Installation**:
   ```bash
   composer require nativecodein/laravel-translation-scanner

No additional configuration is required—auto-discovery handles the service provider.

  1. First Scan: Run the scanner to extract all translation strings from your project:

    php artisan translations:scan
    

    This will:

    • Scan .php, .blade.php, .js, .ts, .jsx, and .tsx files.
    • Append missing translation keys to resources/lang/en.json with the key as the default value.
    • Skip excluded folders (vendor/, node_modules/, etc.).
  2. First Use Case: After scanning, use the extracted translations in your code:

    // Blade
    {{ __('Dashboard') }}
    
    // PHP
    return trans('Welcome Back');
    
    // Inertia React (TSX)
    t("Login");
    

Implementation Patterns

Core Workflow

  1. Scanning:

    • Integrate translations:scan into your CI/CD pipeline (e.g., GitHub Actions) to ensure translations are always up-to-date.
    • Run manually during feature development to catch new translation strings early.
    • Example workflow:
      git add .
      composer require nativecodein/laravel-translation-scanner
      php artisan translations:scan
      git commit -m "feat: add translations for new dashboard"
      
  2. Translation Generation:

    • Use translations:translate to generate translations for target locales (e.g., Spanish, Arabic):
      php artisan translations:translate es ta ar
      
    • Schedule this command in a cron job or Laravel scheduler for periodic updates:
      // app/Console/Kernel.php
      protected function schedule(Schedule $schedule)
      {
          $schedule->command('translations:translate es ta ar')->weekly();
      }
      
  3. Inertia.js Integration:

    • For React/TypeScript projects, ensure your t() calls are consistent:
      // Good: Direct string
      t("Settings")
      
      // Good: Template literal
      t(`Welcome, ${user.name}`)
      
      // Good: Variable (scanner resolves it)
      const key = "Dashboard";
      t(key)
      
    • Avoid dynamic keys (e.g., t(user.customKey)) unless you handle them via custom logic.
  4. Blade/PHP Patterns:

    • Prefer __() for static strings and trans() for dynamic keys with replacements:
      // Static
      __('Homepage')
      
      // Dynamic (with replacements)
      trans('Welcome back, :name!', ['name' => $user->name])
      
    • Use pluralization in Blade:
      {{ __('Post :count', ['count' => $posts->count()]) }}
      
  5. Testing:

    • Add a test script to verify translations are scanned correctly:
      php artisan translations:scan --dry-run
      
    • Use PHPUnit to assert translations exist:
      public function test_translations_are_scanned()
      {
          $this->artisan('translations:scan')
               ->expectsOutputToContain('Added: Dashboard');
          $this->assertFileExists(database_path('lang/en.json'));
      }
      

Gotchas and Tips

Pitfalls

  1. Dynamic Keys:

    • The scanner cannot resolve dynamic keys like t(user.key). Workaround:
      • Use a custom resolver (extend the package or pre-process keys).
      • Example: Replace t(user.key) with t(user.key || 'fallback') in your JS/TS.
  2. False Positives:

    • The scanner may pick up non-translation strings (e.g., t as a variable name). Exclude files/folders via:
      php artisan translations:scan --exclude=path/to/file.js
      
    • Or rename conflicting variables (e.g., const t = 'temp'const temp = 'temp').
  3. Locale-Specific Issues:

    • Right-to-left (RTL) languages (e.g., Arabic) may need manual adjustments for punctuation/placement.
    • Special characters in keys (e.g., key.with.dots) may cause parsing issues in some translation APIs. Sanitize keys:
      // In a custom provider
      $key = preg_replace('/[^a-zA-Z0-9._-]/', '_', $key);
      
  4. API Rate Limits:

    • Free translation APIs (e.g., LibreTranslate) may throttle requests. Mitigate by:
      • Using the built-in usleep(300000) delay (configurable in the package).
      • Caching translated files to avoid re-translating unchanged keys:
        php artisan translations:translate es --cache
        
  5. Inertia.js Edge Cases:

    • JSX expressions like t({ key: variable }) are not supported. Use:
      t(variable) // Supported
      
    • Async t() calls (e.g., in useEffect) may not be scanned. Ensure strings are defined as constants first.
  6. Merge Conflicts:

    • The scanner appends to en.json but may conflict with manual edits. Use:
      php artisan translations:scan --force  # Overwrites en.json (use with caution)
      
    • Git strategy: Commit en.json separately from code changes to avoid merge hell.

Debugging

  1. Dry Run:

    • Test scanning without modifying files:
      php artisan translations:scan --dry-run
      
    • Outputs what would be added without saving.
  2. Verbose Mode:

    • Show detailed scanning logs:
      php artisan translations:scan -v
      
  3. Custom Paths:

    • Scan specific directories:
      php artisan translations:scan --path=app/Http/Controllers --path=resources/js
      
  4. Provider Debugging:

    • If translations fail, check which provider is used:
      php artisan translations:translate es --provider=google
      
    • Add debug flag to see API responses:
      php artisan translations:translate es --debug
      

Extension Points

  1. Custom Providers:

    • Add a new translation provider by publishing the config:
      php artisan vendor:publish --provider="NativeCodeIn\TranslationScanner\TranslationScannerServiceProvider" --tag="config"
      
    • Extend NativeCodeIn\TranslationScanner\Contracts\TranslationProvider:
      class DeepLProvider implements TranslationProvider {
          public function translate(string $text, string $locale): string {
              // Custom DeepL API logic
          }
      }
      
    • Register in config/translation-scanner.php:
      'providers' => [
          'deepl' => \App\Providers\DeepLProvider::class,
      ],
      
  2. Pre/Post-Scan Hooks:

    • Listen to the translations.scanned event to process results:
      // app/Providers/EventServiceProvider.php
      protected $listen = [
          'NativeCodeIn\TranslationScanner\Events\TranslationsScanned' => [
              \App\Listeners\ProcessTranslations::class,
          ],
      ];
      
    • Example listener:
      public function handle(TranslationsScanned $event) {
          foreach ($event->newKeys as $key) {
              Log::info("New translation key: $key");
          }
      }
      
  3. Excluding Keys:

    • Skip specific keys (e.g., internal strings) by adding a .translationignore file:
      # .translationignore
      /^internal\./
      /^temp\./
      
    • Or use the --ignore flag:
      php artisan translations:scan --ignore="internal.*"
      
  4. Post-Processing:

    • Use the translations:scan output to generate TypeScript types for your translations:
      php artisan translations:scan | grep 'Added:' | awk '{print "const " $2 " = \"" $2 "\";"}' > resources/js/translations.d.ts
      

Performance Tips

  1. Incremental Scanning:

    • For large projects, scan specific paths first:
      php artisan translations:scan --path=resources/views
      
    • Use --changed to scan only modified files (requires Git):
      php artisan translations:scan --changed
      
  2. Parallel Processing:

    • The scanner processes files sequentially. For faster scans, consider:
      • Running in parallel (e.g., via Laravel queues):
        // app/Console/Commands/ScanTranslations.php
        public function handle() {
            $files =
        
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui