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

Nova Language Management Laravel Package

crayon/nova-language-management

A Laravel Nova package for managing your application's languages and translations directly from the Nova admin panel. Add, edit, enable, or disable locales and keep localization files organized without touching code. A lightweight way to handle multi-language sites inside Nova.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this package as an admin-facing locale registry for Nova, not as a translation-string system. Confirm that in the source before adopting it.

  1. Audit before install:
    • Open composer.json in the repo/package and check Nova, Laravel, and PHP constraints.
    • Inspect src/ for the Nova tool class, service provider, migrations, config, models, and policies.
    • Check whether migrations/config are auto-loaded or must be published.
  2. Install and register:
    composer require crayon/nova-language-management
    
    Register the tool in app/Providers/NovaServiceProvider.php inside tools() if the package does not auto-register it. Use the exact tool class from the package README/source.
  3. Publish and migrate only if the package exposes assets:
    php artisan vendor:publish --provider="Crayon\\NovaLanguageManagement\\..."
    php artisan migrate
    
    Do not publish blindly; inspect the service provider’s boot() method first.
  4. Seed a minimal set of locales:
    // Example shape; use the package model/table after inspecting source.
    foreach ([
        ['code' => 'en', 'name' => 'English', 'active' => true, 'default' => true],
        ['code' => 'fr', 'name' => 'French', 'active' => true, 'default' => false],
    ] as $language) {
        Language::updateOrCreate(['code' => $language['code']], $language);
    }
    
  5. First use case: create/activate en, fr, and de in Nova, then add middleware that resolves the current locale from the authenticated user, session, Accept-Language, or the default active language.

Where to look first:

  • Package README.md
  • src/ for the Nova tool and service provider
  • database/migrations/ for the languages table schema
  • config/ for cache, table, or middleware options
  • composer.json for Nova/Laravel compatibility

Implementation Patterns

1. Build a small locale resolver around the package.

The package manages available languages; your app still needs to decide which one is active per request.

public function handle($request, Closure $next)
{
    $supported = Cache::rememberForever('languages.active_codes', function () {
        return Language::where('active', true)->pluck('code')->all();
    });

    $default = Cache::rememberForever('languages.default_code', function () {
        return Language::where('default', true)->value('code') ?? config('app.fallback_locale');
    });

    $locale = $request->user()?->locale
        ?? $request->session()->get('locale')
        ?? $this->fromAcceptLanguage($request, $supported)
        ?? $default;

    if (! in_array($locale, $supported, true)) {
        $locale = $default;
    }

    app()->setLocale($locale);
    Carbon::setLocale($locale);

    return $next($request);
}

Register it after session/auth middleware for web routes. For APIs, use Accept-Language and do not rely on session state.

2. Use Nova as the admin workflow, not as runtime config.

Typical admin flow:

  • Add a language in Nova.
  • Mark it active only after translations exist.
  • Set exactly one default language.
  • Clear the locale cache.
  • Test login, dashboard, validation messages, date formatting, and emails.

Give the tool a Gate/policy so only trusted admins can change locales.

3. Cache the active locale list and invalidate on writes.

A database query on every request is unnecessary. If the package model fires standard Eloquent events, add an observer:

class LanguageObserver
{
    public function saved(Language $language): void
    {
        Cache::forget('languages.active_codes');
        Cache::forget('languages.default_code');
    }

    public function deleted(Language $language): void
    {
        Cache::forget('languages.active_codes');
        Cache::forget('languages.default_code');
    }
}

If the package does not fire usable events, wrap writes in your own service/action and clear cache there.

4. Pair language management with a real translation strategy.

This package should not be expected to store translated UI strings. Use one of:

  • Laravel lang/ files for static translations.
  • spatie/laravel-translation-loader or a custom database translation table for editable strings.
  • spatie/laravel-translatable for model content.

Keep the concerns separate: languages/locales are configuration; translations are content.

5. Add a user language preference through a normal Nova field.

Expose a locale select on the user resource populated from active languages. Validate against active codes on save. Then let middleware prefer the user’s stored locale over the session.

6. Seed idempotently for every environment.

Use updateOrCreate by ISO code, not by display name. Keep codes consistent: en, fr, de, not English, French, etc.

7. Treat deployments as locale changes.

Include migrations/seeds for baseline languages and run cache clears after deploy:

php artisan migrate --force
php artisan db:seed --class=LanguageSeeder --force
php artisan optimize:clear

Gotchas and Tips

  • Low adoption risk: 4 stars, zero dependents, and a 2023 release mean you must audit the source and pin the version. Check whether it supports your Nova major version. Test in staging before production.
  • Nova compatibility: Confirm composer.json constraints against your Nova/Laravel/PHP versions. Do not assume Nova 5 or Laravel 11+ support.
  • Not a translation engine: Dynamic language management is not the same as translating content. If you need translated strings, add a translation package or custom table.
  • Protect the default language: Prevent deleting or deactivating the default locale without first assigning another default. Enforce this in validation, a policy, or a model observer.
  • Validate locale codes: Prefer ISO 639-1 codes and reject duplicates. Ensure the database has a unique constraint on the locale code if the package does not provide one.
  • Middleware order matters: Set locale after session/auth middleware, before view composers, translation lookups, and response formatting. API routes need separate resolution logic.
  • Cache invalidation is easy to miss: Clear locale caches on create/update/delete and after deployments. Queue workers and Octane workers can hold stale state if you cache in static properties.
  • Session vs user preference: Decide precedence explicitly. A common order is user preference, then session, then Accept-Language, then default.
  • Fallback mismatch: Keep config('app.fallback_locale') aligned with the package’s default locale, or make the package default authoritative and document it.
  • Nova permissions: Register the tool behind authorization. Locale changes can break routing, emails, and validation messages if exposed too broadly.
  • Testing: Use RefreshDatabase and seed active/default languages because middleware may query the language table. Test invalid locale, inactive locale, missing default, and API Accept-Language.
  • Debugging checklist:
    composer show crayon/nova-language-management
    php artisan route:list --path=nova
    php artisan tinker
    # check app()->getLocale(), config('app.locale'), active language rows
    php artisan optimize:clear
    
  • Frontend locale is separate: This package will not set <html lang>, JavaScript i18n, or localized routes. Handle those in your Blade/Inertia/Vue layer and route groups.
  • Extension points: Prefer wrapping package writes in your own service, observers, policies, and middleware. If the package lacks events or config, keep your integration thin so it can be replaced later.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect