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

Json Fallback Laravel Package

laravel-lang/json-fallback

Laravel Lang JSON Fallback adds a reliable fallback mechanism for Laravel JSON translations, ensuring missing keys resolve to a default locale instead of breaking UX. Simple to install via Composer and integrates cleanly with Laravel’s localization system.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laravel-lang/json-fallback
    

    Add the service provider to config/app.php:

    LaravelLang\JsonFallback\JsonFallbackServiceProvider::class,
    
  2. Publish Config (optional):

    php artisan vendor:publish --provider="LaravelLang\JsonFallback\JsonFallbackServiceProvider" --tag="config"
    

    This generates config/json-fallback.php with default settings:

    'fallback_locale' => 'en', // Default fallback locale
    'json_path' => 'lang/json', // Default JSON path (adjust if custom)
    
  3. First Use Case: Place JSON translation files in lang/json/{locale}.json (e.g., lang/json/fr.json). Use trans() as usual:

    // In Blade or PHP
    {{ trans('auth.login') }} // Falls back to 'en' if 'fr' key is missing
    

Where to Look First

  • Configuration: config/json-fallback.php for fallback locale/path overrides.
  • Service Provider: JsonFallbackServiceProvider registers the custom JsonLoader.
  • Loader Class: JsonFallbackLoader in src/JsonFallbackLoader.php for advanced customization.

Implementation Patterns

Usage Patterns

  1. Standard JSON Translations:

    // lang/json/fr.json
    {
        "auth": {
            "login": "Connexion",
            "register": "Inscription"
        }
    }
    
    // lang/json/en.json (fallback)
    {
        "auth": {
            "login": "Login",
            "register": "Register"
        }
    }
    
    // Blade or PHP
    {{ trans('auth.login') }} // Uses 'fr' if available, falls back to 'en'
    
  2. Dynamic Fallback Locale: Override the fallback locale per request:

    app('json-fallback')->setFallbackLocale('es');
    trans('auth.login'); // Falls back to 'es' if 'fr' key is missing
    
  3. Custom JSON Paths: Configure in config/json-fallback.php:

    'json_path' => 'resources/lang/custom-json',
    

    Then place files in resources/lang/custom-json/{locale}.json.

  4. Integration with Frontend: Use JSON files directly in JavaScript (e.g., via Laravel Mix/Vite):

    // public/js/translations.js
    import fr from '../../lang/json/fr.json';
    import en from '../../lang/json/en.json';
    const translations = { ...fr, ...en }; // Fallback logic in JS
    

    Or fetch dynamically:

    // In a controller
    return response()->json([
        'translations' => trans()->getLoader()->load('fr', 'json')
    ]);
    

Workflows

  1. Translation Workflow:

    • Add new keys to en.json (fallback).
    • Translate to other locales incrementally; missing keys auto-fallback.
    • Use php artisan lang:publish to sync JSON files.
  2. CI/CD Validation:

    • Add a script to validate JSON files for missing keys:
      php artisan lang:json-validate --fallback=en
      
    • Fail builds if critical keys (e.g., auth.login) are missing in primary locales.
  3. Multi-Locale Apps:

    • Set fallback_locale to a "super-fallback" (e.g., en).
    • Use app()->setLocale() to switch languages dynamically.

Integration Tips

  • Laravel Mix/Vite: Copy JSON files to public/lang/ during build:
    // vite.config.js
    copy({
        targets: [
            { src: 'lang/json/*.json', dest: 'public/lang/json' }
        ]
    })
    
  • API Responses: Return translations with API responses:
    return response()->json([
        'data' => $data,
        'translations' => trans()->getLoader()->load(app()->getLocale(), 'json')
    ]);
    
  • Testing: Mock the loader in tests:
    $this->app->instance(
        'translation.loader',
        new JsonFallbackLoader($this->app)
    );
    

Gotchas and Tips

Pitfalls

  1. Nested JSON Structures: The package assumes flat key-value pairs. Nested JSON (e.g., {"key": {"subkey": "value"}}) will not work without preprocessing. Flatten keys manually:

    // Before (broken)
    { "auth": { "login": "Connexion" } }
    
    // After (fixed)
    { "auth.login": "Connexion" }
    
  2. Caching Issues: Clear translation cache after adding new JSON files:

    php artisan view:clear
    php artisan cache:clear
    
  3. Fallback Locale Overrides: Changing fallback_locale dynamically affects all subsequent translations. Reset carefully:

    app('json-fallback')->setFallbackLocale('en'); // Reset to default
    
  4. Missing JSON Files: If lang/json/{locale}.json doesn’t exist, the package will fail silently (no fallback). Ensure all locales have a JSON file, even if empty:

    // lang/json/fr.json (empty is fine)
    {}
    
  5. Conflicts with Other Loaders: If using multiple translation loaders (e.g., spatie/laravel-translation-loader), ensure JsonFallbackLoader is registered last to avoid priority conflicts.

Debugging

  1. Check Loaded Translations: Dump the loaded JSON for debugging:

    dd(app('translation')->getLoader()->load('fr', 'json'));
    
  2. Verify Fallback Logic: Temporarily disable fallbacks to test:

    app('json-fallback')->disableFallbacks();
    trans('auth.login'); // Will return null if key is missing
    
  3. JSON Syntax Errors: Validate JSON files with:

    php artisan lang:json-validate --locale=fr
    

Tips

  1. Key Consistency: Use a tool like laravel-lang/macroable to enforce key naming conventions across JSON files.

  2. Performance: For large JSON files, consider compressing or lazy-loading translations:

    // In JsonFallbackLoader.php
    public function load($locale, $group, $namespace = null) {
        $file = $this->getFile($locale, $group, $namespace);
        return json_decode(file_get_contents($file), true) ?: [];
    }
    
  3. Fallback Hierarchies: For multi-level fallbacks (e.g., fr-CAfr-FRen), extend the loader:

    // app/Providers/JsonFallbackServiceProvider.php
    public function register() {
        $this->app->bind('translation.loader', function ($app) {
            return new CustomJsonFallbackLoader($app, [
                'fr-CA' => ['fr-FR', 'en'],
                'fr-FR' => ['en']
            ]);
        });
    }
    
  4. Dynamic Fallbacks: Set fallback locales per request based on user preferences:

    $fallback = auth()->user()->preferred_fallback ?? 'en';
    app('json-fallback')->setFallbackLocale($fallback);
    
  5. Testing Fallbacks: Use Translatable facade for assertions:

    use LaravelLang\JsonFallback\Facades\Translatable;
    
    $this->assertEquals(
        'Fallback Value',
        Translatable::trans('missing.key', [], 'fr')
    );
    
  6. Backup Fallback: Add a "super-fallback" for critical keys:

    // In a middleware or service provider
    app('json-fallback')->setSuperFallback(function ($key, $locale) {
        return "Default: {$key}";
    });
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests