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

Localization Core Filament Laravel Package

liberusoftware/localization-core-filament

Filament admin panel integration for Localization Core. Manage locales, translation keys, and language files from your Filament dashboard, with resources and UI components for editing translations without leaving the admin area.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a presentation adapter, not a standalone localization package. It assumes liberusoftware/module-localization-core (the domain layer: models, contracts, services) is installed and supplies the actual persistence and business rules. Your job as a developer is almost never to touch this package's internals — it's to register the panel plugin, point your Filament panel at it, and let it render the resources the core exposes.

Minimal path to a running screen:

composer require liberusoftware/module-localization-core \
                 liberusoftware/module-localization-core-filament

Then, in order:

  1. Inspect composer.json before anything else. Confirm the Filament major version constraint (filament/filament:^3.0 vs ^4.0) and the PHP/Laravel floor. Filament v3→v4 moved the form/table namespaces; if the constraint is v3 and your panel is v4, stop here and pick a different approach.
  2. Publish and run the core migrations, not the adapter's. Migrations belong to the core module (database/migrations inside module-localization-core). The adapter should only contain Filament classes. If you see loadMigrationsFrom in the adapter provider, read it carefully before publishing twice.
  3. Register the provider/plugin in your panel provider (app/Providers/Filament/AdminPanelProvider.php). Liberu adapters typically ship either a Plugin class (->plugin(LocalizationCoreFilamentPlugin::make())) or a plain service provider listed in bootstrap/providers.php. Check src/ for which pattern this one uses — plugin is preferred because it scopes resources to a single panel.
  4. Clear the Filament caches after registering: php artisan filament:optimize-clear && php artisan optimize:clear. Stale component caches are the #1 cause of "resource not showing up."

Where to look first: src/Providers/ → src/Filament/Resources/ (the actual UI surface) → src/Filament/Pages/ (import/export, translation editor) → config/ in the core package (locale list, fallback behaviour, driver bindings). The adapter's public API is effectively "which resources and pages exist and what their names are."

First use case: create a locale record, add a translation key under a group, add values per locale, then visit the front end with ?lang= or App::setLocale() to confirm the read path resolves through the core. If the front end still reads lang/*.php files and ignores the DB rows, you haven't wired the core's translation loader — see Gotchas.

Implementation Patterns

Treat the adapter as read-mostly and extend by subclassing. Don't fork the vendor resources. Instead:

namespace App\Filament\Resources;

use Liberusoftware\LocalizationCoreFilament\Filament\Resources\LocaleResource as BaseLocaleResource;

class LocaleResource extends BaseLocaleResource
{
    public static function getNavigationGroup(): ?string
    {
        return 'Settings';
    }

    public static function getNavigationSort(): ?int
    {
        return 99;
    }
}

Then hide the vendor resource (many Liberu adapters expose a ->resources([...]) or ->discoverResources() toggle on the plugin) and register your subclass. This survives composer update; a fork does not.

Keep domain logic in the core. The adapter's forms and actions should call core services/actions (CreateLocale, SyncTranslationsFromFiles, whatever the core exposes), never Locale::create() directly in a Filament ->action(). This keeps your Artisan commands, API endpoints, and admin UI behaviourally identical. If the core has no action for what you need, add it there and open a PR upstream rather than embedding it in a Filament closure.

Multi-panel and multi-tenant. If you run separate admin and tenant panels, register the plugin only where it belongs. For tenant-scoped translations, override resource queries with ->modifyQueryUsing(fn ($query) => $query->where('tenant_id', Filament::getTenant()?->id)) on the table and add the tenant column on create. Global keys (validation messages, mail subjects) usually need an explicit "global" flag in the core rather than a bypass in the UI.

Translation editor workflow. The pragmatic day-to-day pattern is: developers add keys in code, an admin edits values in Filament. Support that with a bulk action that runs the core's file-scan/sync, a TextColumn for "coverage" (values present / locales), and a filter for missing values. Avoid inline editable columns for large tables — they generate one Livewire request per keystroke commit and are painful at 10k+ keys.

Authorization. Map the adapter's resources to policies/permissions rather than relying on panel access alone. canViewAny, canCreate, plus a ->visible() guard on the navigation item. In a Liberu-style modular install, permissions usually come from the core's seeder — run it, don't hand-roll a policy that drifts.

Testing. Use Livewire resource tests against the real panel:

Livewire::actingAs($admin)
    ->test(ListLocales::class)
    ->assertCanSeeTableRecords($locales)
    ->callTableAction('create', data: ['code' => 'pt_BR', 'name' => 'Português (Brasil)'])
    ->assertHasNoTableActionErrors();

RefreshDatabase with the core's migrations is enough; you rarely need the adapter's own fixtures.

Gotchas and Tips

  • License is NOASSERTION. That is not a permissive license — it means the repo's LICENSE file is missing or unparseable by GitHub. Get legal sign-off before shipping this in a commercial product, and check composer.json for a license field that may contradict the repo.
  • Zero stars, zero dependents, first release dated 2026. Treat the public API as unstable. Pin an exact version ("liberusoftware/module-localization-core-filament": "1.2.3", not ^1.0), and keep your subclasses in one directory so a breaking change is a single-file fix.
  • Provider order matters. The core service provider must boot before the adapter, otherwise container bindings for the translation repository aren't there when Filament resolves the resource. Check bootstrap/providers.php ordering, and remember composer dump-autoload after moving entries.
  • Migrations are a classic double-publish trap. If both packages expose the same migration (or the adapter re-publishes core stubs), you'll get "table already exists" on a fresh migrate. Publish once, from the core, into database/migrations and commit them.
  • The front end may not use the DB at all. Filament screens writing to a translations table does nothing for __('messages.welcome') unless the core registers a translation loader (typically a spatie/laravel-translation-loader-style driver) in config/app.php or via a service provider. Verify by changing a value in the UI and hitting a page that uses the key.
  • Cache invalidation is manual. Most loaders cache aggressively. After bulk edits you need php artisan cache:clear (or the core's dedicated translations:cache-flush). Bake it into the after-save hook of your import action, or admins will swear the UI is broken.
  • Fallback locale conflicts. The core config, config/app.php fallback_locale, and the DB locale table can all disagree. Pick the DB as the source of truth for available locales and app.fallback_locale for resolution, and assert that the fallback locale exists in the table at boot (a failing test is cheaper than a 500 in production).
  • N+1 on translation tables. Eager-load values with ->with('values') in list tables, or use a SelectColumn/TextColumn backed by a single aggregate query. A naive values->firstWhere(...) per row is a per-row query on every render.
  • Extension points to prefer: container bindings for the repository/driver interfaces (override in AppServiceProvider::register), Filament render hooks (FilamentView::registerRenderHook) for extra panels on existing pages, and ->configureUsing() on resources for global tweaks. Avoid reflection or overriding protected methods; they're the first thing to break on minor releases.
  • Debugging checklist when nothing renders: php artisan about (confirm Filament panel count), php artisan filament:optimize-clear, php artisan route:list --path=admin | grep -i local, then dump the registered plugin list. Nine times out of ten it's a stale component cache or the plugin registered on the wrong panel.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
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
cgv/localized-resource