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

webx-ui/localization

Webx UI Localization brings localization tools to your Laravel UI. It offers helpers and components for managing translations, switching locales, and keeping multilingual interfaces consistent, so you can ship apps that feel native across languages with less effort.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

The storage-model decision — treat it as a one-way door and own it explicitly. This package answers a narrower question than "should we internationalize?" It answers: do we store translated content in per-locale columns/tables, or in a single JSON map on the row? It commits hard to the JSON map via HasTranslations and $table->translatable(). Migrating out of JSON maps into per-locale tables later is a data migration, not a config change. Make that call deliberately, with content volume and reporting needs in hand, before the first translated row is written, and record it with a named owner.

Feature scope for a localized public site plus an admin panel. The package ships the full minimum viable loop: a locales table with a single enforced default, a Locales service with fallback chaining, prefix-based request resolution, and panel dictionary publishing. This supports a roadmap decision like "ship v1 in N languages with prefix routing and an English-only admin UI" without writing locale plumbing. The 'strategy' => 'prefix' | 'header' | 'none' switch lets you defer the SEO/URL-structure debate — but it is a launch-time decision with permanent redirect implications, not a toggle you flip after launch.

SEO and URL architecture. OneSpellingPerAddress encodes a real product rule: unknown locale prefix → 404, default locale prefix → 301 to the unprefixed address unless prefix_default is on. PMs relitigate canonical-URL policy mid-project more often than any other SEO question. Having it enforced by middleware instead of by convention is worth a lot. Note the boundary: translated slugs are explicitly delegated to webx-ui/routing and are not covered here — scope that as a separate workstream or you will promise something this package cannot deliver.

Content lifecycle and data-retention policy. The docs make an opinionated, PM-relevant call: never delete a language to hide it — set is_active = false, because translated text persists in every JSON map. That underwrites a product policy ("we can retire a language from the UI without losing the corpus"), which matters for re-launch decisions, legal/archival obligations, and content-team trust. It also pre-empts the classic expensive mistake: an engineer deletes the row and the content is orphaned.

Localizing the admin experience as its own budget line. Panel language is a distinct concern from public-site language (webx.panel-locale vs webx.locale, plus a separate 'panel' config list). That lets you plan "public site in 6 languages, admin in 2" without conflating the two. It also surfaces the true cost: panel translation means translating published lang files per module — a recurring vendor-content cost that scales with modules × languages, not a one-time engineering task.

Translation completeness and fallback as a quality-vs-speed tradeoff. 'fallback' decides which language fills a gap. Read it as a shipping posture: fallback on an incomplete language produces mixed-language pages that users notice and report. Decide explicitly whether missing translations should fall back (ship faster, uglier) or be surfaced (ship slower, cleaner). The package supports either but defaults you into one — so the default becomes your policy unless you intervene.

Risk framing on the dependency itself. Stars 0, dependents 0, a read-only split of a monorepo. That is not a quality signal; it is a signal that this is an internal component published for the framework's own users. Your decision is therefore about adopting webx-ui as a platform, not about adopting this package à la carte. Frame it that way in any steering deck or the risk read will be wrong in both directions.

When to Consider This Package

Consider it when:

  • You are already building on webx-ui. The routes, caches, and routing this package depends on live in sibling packages (module-admin, routing, cache); outside that stack you inherit only a fraction of the value.
  • You want translated Eloquent attributes without join tables — modest content volume (thousands, not millions of rows), a handful of languages, read-heavy public pages with caching in front.
  • You need SEO-correct locale prefixes with enforced 301/404 semantics on day one rather than as a later cleanup.
  • You value opinionated guardrails. The "Do not" list (don't edit vendor, don't delete languages, don't set is_default via raw SQL, don't index translated slugs in the DB) is a support-cost reducer — it tells you which footguns the maintainers have already paid for.
  • You need a narrow, documented extension surface. The "Change it without forking" table enumerates every supported customization. That is an unusually honest contract and materially lowers fork risk.
  • You can budget the cluster, not the package. Plan for localization + routing + module-admin + cache as a three-to-four package unit, with pinning and upgrade rehearsals covering all of them.

Look elsewhere when:

  • You are not on webx-ui. At 0 dependents there is no evidence of standalone adoption or standalone support, and the package assumes its siblings exist.
  • You need translation workflow tooling — TMS integration (Crowdin, Lokalise, Phrase), translator review queues, per-string status tracking, or content-freeze/approval flows. None of that is here, and it likely is not in the monorepo either.
  • You need database-enforced per-locale uniqueness (e.g. unique slugs per language). Explicitly out of scope and genuinely hard against JSON columns. If your product requires it, the storage model is wrong for you — not the package.
  • You need to query, sort, or aggregate heavily on translated fields, or run analytics over per-language content. whereTranslation/orderByTranslation exist but will not match native-column performance at scale.
  • You require mature community support: an issue tracker with history, third-party tutorials, security advisories, an inspectable release cadence. Issues and PRs route upstream to the monorepo — vet that repository's activity before committing.
  • You need locale negotiation beyond prefix/header/none (subdomain, TLD, user-profile-based, A/B-tested locale) or per-locale URL structures. That is routing's business.
  • You need documented Laravel/PHP support ranges and a versioning policy. These are undocumented in the source excerpt; absence of an answer is itself a decision input.

How to Pitch It (Stakeholders)

To executives — one paragraph. This is the localization layer of the webx-ui platform we would be adopting, not a standalone library. It gives us multi-language public pages and a translated admin panel with the unglamorous parts already solved: one enforced default language, correct SEO behavior for language-prefixed URLs, the ability to retire a language without data loss, and caching that stays coherent. The cost profile is low and predictable — MIT licensed, no vendor contract, no per-seat fees. Two caveats to carry forward: it is early-stage with no independent adoption, so we take on framework-coupling risk; and the content-storage model (translations in a JSON column) suits our content volume today but would need rework if we ever require database-level per-language uniqueness or heavy per-language reporting. Recommendation: adopt as part of a webx-ui platform decision, not as an isolated bet, and treat translated-slug handling as a separate workstream to be scoped with webx-ui/routing.

To engineering — the short version. Four things worth knowing before you estimate. (1) Storage: HasTranslations + $table->translatable() puts all locales in one nullable JSON column — no joins, no per-locale schema churn, but no per-locale indexes and no DB-level uniqueness; slugs are explicitly routing's problem. (2) State: the locales table wins over config after migration; config is seed-only; exactly one default is enforced by the model rather than the schema — so any bypass of the model requires a cache clear. (3) Request resolution is middleware aliases (webx.locale, webx.panel-locale) plus OneSpellingPerAddress, which makes unknown prefixes 404 and the default prefix a 301 — that is a tested invariant, don't reimplement it. (4) Extension is by published config, published lang tags, and model traits; editing vendor/ is unsupported, and a missing seam is a bug to report upstream rather than work around. Estimate panel translation separately — it scales with modules × languages, not with our code.

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