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

Laravel Translatable Laravel Package

taxionus/laravel-translatable

A Laravel package for adding multilingual attributes to Eloquent models, letting you store and retrieve translations per locale so your app can serve content in multiple languages.

View on GitHub
Deep Wiki
Context7

Getting Started

This is the package's first tagged release (1.0.0), so there is no upgrade path to consider — treat it as a greenfield integration and pin it explicitly in composer.json rather than relying on a floating constraint while the public API settles.

Start here, in this order:

  1. composer require the package at ^1.0.0 and confirm the service provider is picked up by Laravel's package auto-discovery (php artisan about will show it, or php artisan package:discover on older skeletons). If the package ships a facade or a Manager-style class, resolve it from the container once in tinker before touching application code — that single check tells you whether config, credentials and bindings are wired.
  2. Publish and read the config file (php artisan vendor:publish --provider="...ServiceProvider" --tag=config). On a 1.0.0 release the config is the de facto contract: defaults tell you what the package assumes about your app (driver, queue connection, table names, cache TTL). Diff the published file against the package's own copy in vendor/ — drift here is the most common first-day confusion.
  3. Publish migrations/templates if present and run php artisan migrate on a fresh database, not your dev DB. A first release frequently has index/foreign-key assumptions that only surface on a clean schema.
  4. Check the README's "quick start" snippet against the actual source. For an initial release, the readme is often written against a pre-1.0 API. If they disagree, the source wins.

First use case: wire up the smallest end-to-end path the package offers — one create, one read — inside a throwaway route or an artisan command, not inside a controller. You want to verify container resolution, config loading, and the storage/transport layer in isolation before that code is entangled with your HTTP concerns. Once that green path works, immediately exercise the failure path (missing credential, unreachable service, invalid payload) because first releases tend to have thin error handling.

Implementation Patterns

Resolve through the container, never new. Bind the package's client/manager in a dedicated service provider of your own and inject it, so you have one place to swap config, add retries, or fake it in tests:

$this->app->singleton(PackageClient::class, fn ($app) => new PackageClient(
    config('package.api_key'),
    $app->make(GuzzleHttp\Client::class),
));

Wrap it in your own thin adapter. Do not let package classes leak into controllers, models or Blade. A single App\Services\... class that exposes the three or four operations you actually use means the package's inevitable 1.x API churn costs you one file, not forty. It also gives you a seam for logging and metrics.

Push side-effecting calls onto the queue. Anything that hits a network or slow store should be a job with $tries, $backoff and failed() implemented. First releases commonly lack built-in retry semantics; your job wrapper is where you supply them. Use ShouldBeUnique if the operation is idempotency-sensitive.

Keep the package's own events and your domain events separate. If it fires events, listen to them and re-emit your own domain events rather than dispatching application events from inside a package listener — otherwise you inherit their payload shape as a public contract.

Test with a fake, not a mock. If the package ships a fake()/swap() helper, use it in feature tests and keep a small number of integration tests that hit the real thing behind a @group integration annotation. If it ships no fake, that is your first contribution — it is the single highest-leverage addition to a 1.0.0 package.

Config over code for environment differences. Every value you would plausibly change between local/staging/production (endpoint, TTL, driver, queue name) belongs in config/ and read via config(), referenced by env var in .env.example. Never call env() outside config files — it returns null once config is cached, and this bites hardest with freshly released packages.

Log with context on the boundary. One log line at the adapter boundary including the operation, a correlation/request id, and duration. When something misbehaves in production, this is the difference between a five-minute and a five-hour diagnosis.

Gotchas and Tips

  • env() after config:cache. Classic first-release killer. If the package reads env() at runtime internally, php artisan config:cache in a deploy will silently blank its credentials. Verify by running config:cache locally before you ship.
  • Auto-discovery versus manual registration. If you also add the provider to config/app.php (legacy habit), you get double registration — duplicated migrations, doubled listeners, doubled middleware. Pick one.
  • Publish tags are not stable. vendor:publish --tag=... tags are commonly renamed between 1.0.0 and 1.0.1. Run it once early, commit the published files, and stop re-publishing.
  • Loose version constraints on a 1.0.0. ^1.0 is fine after you have tests pinning behaviour; before that, tag-lock (1.0.0) so a 1.0.1 patch cannot change behaviour under you mid-sprint.
  • Migrations in packages run in your app's context. They inherit your default connection and your migrations table. On multi-tenant or multi-connection setups, confirm which connection the package assumes before migrating anywhere real.
  • Facade docblocks lie. IDE helper blocks in a first release routinely promise methods that return mixed or were renamed. Trust vendor/ source or php artisan ide-helper:generate output over the shipped docblock.
  • Silent no-ops on misconfiguration. Many packages degrade to doing nothing rather than throwing when a key is missing. Add an explicit boot-time check (a booted() callback or a health-check command) that validates required config and fails loudly in non-local environments.
  • Debugging order: php artisan about → php artisan config:show <package> → resolve the binding in tinker → enable the package's own debug/log channel → finally reach for Xdebug. Most first-release issues are config-shaped, not code-shaped.
  • Extension points to look for: a Manager class with extend(), a driver config array, or interfaces bound in the provider. If any exist, prefer them over subclassing concrete classes — subclassing a 1.0.0 internals is the fastest route to a painful 1.1.0 upgrade.
  • Report issues upstream early. A 1.0.0 is the cheapest moment to influence the API. Keep a docs/vendor-notes.md of workarounds you apply; if the package fixes them, that file is your upgrade checklist.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core