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 Translatable Laravel Package

yeswedev/nova-translatable

A Laravel Nova field for editing translatable model attributes across locales, integrating with spatie/laravel-translatable so you can manage multi-language content directly in Nova forms.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install: composer require yeswedev/nova-translatable. Before committing, open the package's composer.json and check its laravel/nova and spatie/laravel-translatable constraints — small packages often pin one Nova major version.
  • Prerequisite: it almost certainly assumes a spatie-style translatable model. Your model needs use HasTranslations;, public $translatable = ['title', 'body'];, and the underlying columns must be JSON.
  • Publish assets/config: php artisan vendor:publish --provider="YesWeDev\NovaTranslatable\..." (check vendor/yeswedev/nova-translatable/ for a service provider, config/, and resources/views/). If a config/nova-translatable.php exists, it's where the locale list and default locale live.
  • Where to look first: the field class in src/ is the real documentation. Read its constructor and fluent methods to learn whether locales come from config or a ->locales([...]) call, and whether it's a wrapper around other Nova fields or a fixed text input. The README is short; the source is authoritative.
  • First use case: on a resource whose model already uses spatie translatable, swap one field — Text::make('title') → the package's translatable field — and load the form. You should see one input per configured locale (tabs or stacked). If you see a single input, the locale list isn't resolving from config — fix that before wiring up more fields.

Implementation Patterns

  • Field swap, one attribute at a time. Replace plain fields for $translatable attributes only; leave everything else untouched. If it's a wrapper, you can pass Text, Textarea, Trix, or Markdown into it; if it's a fixed input, that's a hard constraint to plan around.
  • Centralize locales. Put the locale list in package/app config rather than ->locales([...]) on every field. One change updates every resource and prevents drift between forms.
  • Keep related translatable fields together. If locale tabs are rendered per-field, grouping all translatable fields in the same panel/tab makes the switcher feel coherent. Splitting them across panels tends to produce multiple stacked locale switchers and a confusing edit experience.
  • Index/detail display. Either use the package's display field, or handle it yourself: Text::make('Title', fn ($m) => $m->getTranslation('title', app()->getLocale())). Never let a listing dump raw translation JSON.
  • Validation. If per-locale rules aren't built in, use a closure: require only the default locale, allow blanks elsewhere, and target rule keys like title.en / title.fr against the actual request payload shape (verify this — it's the usual Nova array-field format but confirm).
  • Write path. Keep $fillable and $casts correct on the model and let Nova's normal fill write back. If the package calls setTranslations() directly instead, don't add conflicting casts or accessors.
  • Suggested workflow: define locales → verify $translatable → swap fields on one resource → test save/load per locale → add index display → add per-locale validation → template to other resources.

Gotchas and Tips

  • Adoption is essentially zero (2 stars, 0 dependents). Treat it as an internal package: read src/ end to end, don't assume fluent methods exist because a sibling package has them, and vendor-pin the version.
  • JSON column support. MySQL 5.7+, Postgres jsonb, SQLite json. If the column is TEXT on an older MySQL, saves/loads can fail silently or round-trip incorrectly.
  • Fallback mismatch. spatie's getTranslation(..., $fallback) and whatever the display field does are separate code paths. Explicitly test the blank-locale case on detail/index, or you'll ship empty cells where a fallback was expected.
  • Search/sort don't work on JSON. ->searchable() and ->sortable() against a translatable attribute need a generated/virtual column or a whereJsonContains scope. The package almost certainly doesn't solve this — don't assume it does.
  • Tab state is lost on validation failure. After a failed save, the form typically snaps back to the default locale tab. Test a deliberate validation error while editing a secondary locale; if it's annoying, look for a preserveActiveLocale-style option or publish/customize the view.
  • ->rules('required') is the classic trap. It applies to every locale input, so editors can't save unless all translations are filled. Wire per-locale rules on day one.
  • Two sources of default locale. Package config and app.locale often disagree, and the field's default tab may follow one while fallback display follows the other. Pick one, document it, and make the default tab match editorial expectation.
  • Extension points. Prefer publishing and overriding views/config over forking. If a locale-resolver callback exists, use it for per-user locale preference instead of hardcoding.
  • Upgrade risk. Nova 4→5 changes the field API; small packages lag. Smoke-test every translatable resource after any Nova upgrade, and scan the package's changelog (or diff src/) before bumping.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager