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 Translations Loader Laravel Package

optimistdigital/nova-translations-loader

A Laravel Nova package that loads PHP translation files into the Nova front-end, making existing language strings available to Vue components and tools without duplication. It supports multiple locales and lets you localize custom Nova cards, fields, and tools using your app's existing translation f...

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm you're the intended user. This package is for people who author Nova extensions — Tools, Cards, Fields, Resources, internal packages — that ship their own strings and need them available inside Nova's Vue frontend. If you only use Nova and your lang/ files are for the app itself, you don't need this: Laravel's loadTranslationsFrom() and Nova's locale handling already cover you. It earns its place when you have a second, third, or fourth Nova package and you're copy-pasting the same registration block into each service provider.

Minimal steps

  1. composer require optimistdigital/nova-translations-loader in the extension package's composer.json, as a hard require. The tool's UI renders raw keys without it, so it is not a dev dependency.
  2. Publish the config so the scanned paths/namespaces are explicit rather than implied: php artisan vendor:publish --tag=nova-translations-loader-config (confirm the tag in the README).
  3. In your tool's service provider boot(), hand the loader your lang directory:
use Outl1ne\NovaTranslationsLoader\NovaTranslationsLoader;

public function boot()
{
    parent::boot();

    NovaTranslationsLoader::loadTranslations(__DIR__ . '/../resources/lang');
}
  1. Create resources/lang/en/my-tool.php returning ['title' => 'My Tool', 'actions' => ['save' => 'Save']], plus a de equivalent.
  2. In your Vue component use the key the same way you would in Laravel: this.__('my-tool::title') (or whatever helper your Nova version exposes on the component).
  3. Switch the language in the Nova user profile and load the tool.

Where to look first: the README example, then src/ — it's a service provider plus a small loader class, readable in one sitting. Verify the current class/method names there before copying snippets, because the package moved from the optimistdigital to the outl1ne namespace in the 5.x line.

Implementation Patterns

Register once, in the package's own provider. Don't register from the host app — that defeats the point and reintroduces the boilerplate you adopted the package to delete. Put the call in the provider Nova auto-discovers for your tool so it runs before the tool's menu entry and assets render.

Namespace = package handle, one folder per locale. Treat the loader as a convention enforcer: resources/lang/{locale}/{namespace}.php, where the namespace matches the tool's handle. Every internal Nova package then looks the same, and a new package inherits the pattern by copying a neighbour.

Split PHP arrays from JSON by intent. Nested PHP files for grouped UI copy (tool.actions.save); JSON only when you're keying on source strings for a small, mostly-translated surface. Mixing them in one package makes it impossible to answer "where does this string live?" without grepping two trees.

The day-to-day loop is four steps. Adding a string should never be more than: (1) add the key to en, (2) add it to other locales or let fallback cover it, (3) reference it in Vue as namespace::key, (4) reload the page and confirm it renders. If any of those steps requires touching a service provider, your convention has drifted.

Host-app overrides are the feature your product team will actually use. Ship sane defaults in the package's en file, then let the app override a specific string by adding its own lang file. Test this explicitly — the common assumption that Laravel's normal vendor-override precedence applies is exactly the kind of thing that gets silently inverted by a loader that reads files directly. Prove which file wins before you promise it to anyone.

Locale fallback is a file-existence problem. Make sure every configured locale has a file and that fallback_locale has one too. A missing de file should fall back to en, not to the key.

Standardise across the estate with one base provider. If you maintain several Nova packages, put the loader call in a shared NovaPackageServiceProvider base class and let each package extend it. This is the point where the dependency pays for itself; below three or four packages, a 30-line loop in your own provider does the same job.

Test it as a render, not as a config. A unit test asserting Lang::has('my-tool::title') is cheap and worth having, but it does not prove the string reaches the browser. The test that matters is a feature/HTTP test (or a manual checklist step) that sets the locale, hits the tool page, and asserts the translated text is present. Add "load one Nova screen and confirm a known localised string renders" to your release checklist — that single step catches nearly every failure mode below.

Gotchas and Tips

The failure mode is silent and user-discovered. Nothing throws when a namespace fails to register — the operator sees my-tool::title in the admin UI, and the first assumption is an app bug. Debug backwards: browser devtools first (find the translation payload Nova inlined for the page and check whether your namespace is in it), then the PHP side (does the path exist, is the filename equal to the namespace, did the provider actually boot).

Cache layers, in the order they bite. php artisan config:cache is the classic — if the loader reads config at boot, a stale cache can point at the wrong path or skip discovery entirely. Then the tool's compiled assets (npm run dev / production build), then Nova's own asset state, then the browser. php artisan optimize:clear plus a hard reload resolves most "it worked yesterday" reports.

Duplicate registration overwrites silently. If the host app also calls loadTranslationsFrom()/addNamespace() for the same namespace, whichever runs last wins and strings vanish with no error. Inventory existing manual registrations before adopting; the migration step is delete the old boilerplate, not add alongside it.

Translations are captured at boot, not per locale switch. Because the payload is built when the page renders, changing locale typically requires a reload before strings update; don't file that as a bug. If discovery runs per request rather than being cached, you're touching the filesystem on the admin path — cheap now, a latency footnote later as package count grows.

Version alignment is the real integration cost. 5.0.3 is a Nova 5 compatibility patch, which means the package line is pinned to a Nova major. Confirm with composer why-not outl1ne/nova-translations-loader that your PHP/Laravel/Nova floors resolve on every environment including CI and queue workers, and confirm whether the 5.0.x line still supports Nova 4 if you have environments mid-upgrade.

Don't let it reach customer-facing surfaces. This is admin-layer convenience at 39 stars with a single-maintainer lineage. Pin the exact version, record it next to the Nova version per environment, and note in your dependency register that forking is the exit — the code is small enough that this is an hours-scale fallback rather than a project.

Extension points are thin, and that's fine. The publishable config (paths, namespaces) is about the extent of it. If you need more than that, write your own provider — the package's entire proposition is deleting repetitive registration, and it should be abandoned the moment it stops doing that cleanly.

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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package