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

Js Localization Laravel Package

andywer/js-localization

Bring Laravel's translations to JavaScript. An artisan command exports your PHP lang files, and a lightweight client-side translator looks up keys and replaces placeholders at runtime, so backend and frontend share the same strings with no duplication. Works with any frontend stack.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

The package is a thin serialization adapter sitting on top of Illuminate\Translation\Translator. It contributes a service provider, a config file, a facade (JS in the published docs; JSLocalization in the source-era writeups — see key questions), and a Blade directive, then renders the active locale's translation array into a browser-global Lang object exposing get, has, and choice.

Where it fits: a Laravel monolith that renders Blade server-side with islands of JavaScript — form validation copy, toasts, confirmation dialogs, small widget labels. Where it does not fit: Inertia/React/Vue SPAs, Vite module graphs, TypeScript frontends, or anything requiring runtime locale switching. There is no ESM export, no type definitions, no build-time extraction, and no per-locale artifact model. Treat the architectural decision as "PHP lang/ files are the single source of truth and the browser is a read-only consumer of a generated artifact" — a commitment that affects who can change copy and how copy ships.

Integration feasibility

Mechanically it is a half-day: composer require, vendor:publish, add one <script> tag, call JS::put() from a service provider. The real cost is elsewhere and should dominate the estimate:

  • Compatibility validation. The codebase originates in the Laravel 4/5 era. Expect composer.json constraints to fail resolution against Laravel 9/10/11 and PHP 8.1+, and expect removed helpers (array_get, str_*), facade accessor signatures, and Blade directive registration to need patching. Budget a 2–3 day spike with a hard go/no-go before any roadmap commitment.
  • Ownership. With 143 stars and zero Packagist dependents, this is not a dependency you consume — it is ~100–300 lines of glue you adopt. The viable plan is vendor-or-fork, not composer-pin-and-hope.
  • Supply-chain diligence. The linked repository (andywer/laravel-js-localization) and the documented install target (andywer/js-localization) are not obviously the same artifact, and the documented facade (JS) does not match the class name in the older writeups (JSLocalization). Confirm which Composer package the docs actually describe before anyone runs composer require.

Technical risk

Ranked for a risk register:

Risk Severity Note
Unmaintained dependency in the page-render path High Single maintainer, no release cadence, no CI evidence. Mitigate by vendoring.
Over-exposure of translation payload High Bulk export ships admin-panel, email, and back-office validation strings to anonymous users. Must be an explicit allowlist, never putAll().
Runtime file writes to public/ High Fails or silently no-ops on read-only images, Lambda, Heroku ephemeral filesystems. Must move to deploy-time generation.
Injection / escaping Medium Translation values are content interpolated into a JS file; quotes, backticks, </script> produce XSS or syntax breakage.
Pluralization parity drift Medium JS Lang.choice reimplements Laravel's pipe/range rules; divergence is silent and untested.
Locale frozen per page load Medium One global file, single active locale. Per-user locale switching requires per-locale artifacts — a redesign, not a config change.
Concurrent overwrite races Low–Medium Varying group sets per request yield partial or last-writer-wins content.

Key questions

  1. Which Composer package and repository are authoritative, and what is the last commit/release date?
  2. What Laravel and PHP versions are supported today, and does it install cleanly on our target version without constraint overrides?
  3. Does it handle JSON lang/*.json files, vendor::file.key namespaced keys, and nested arrays — or only flat PHP arrays?
  4. How are values encoded into the generated JS, and can a translation string break out of script context?
  5. Is the payload rebuilt per request, or is there a cache/artifact layer with sensible headers?
  6. What is the parity story for Lang.choice against trans_choice for range-based rules, and is there a test harness for it?
  7. Does the export path support per-locale output, or is single-locale a hard constraint?

Integration Approach

Stack fit

Qualify the target application against four criteria before committing: (a) Laravel monolith with Blade as the primary rendering layer; (b) PHP lang/ files already the trusted source of copy; (c) a bounded, enumerable set of client-side strings — hundreds, not thousands; (d) no non-engineer translator workflow in the near term. Missing any of these shifts the recommendation to a JSON endpoint plus a ~30-line Lang helper, which delivers the same pattern with none of the dependency risk.

Migration path

Adopt the pattern, not the package. Sequence the work so the package is a temporary implementation detail behind a boundary we own:

  1. Define an internal contract — e.g. TranslationExporter::export(string $locale, array $groups): array — and a companion Artisan command app:export-lang.
  2. Implement that contract once using the package's internals (or a hand-rolled port, if the compatibility spike fails).
  3. Emit to a build artifact path, versioned and cache-busted, rather than writing on boot.
  4. Serve through the same Lang.get / Lang.choice contract the frontend will use regardless of backend.

The swap to a JSON route, a Vite-imported locale module, or a TMS CDN artifact then becomes a one-file change with no frontend churn. This boundary is the single most important deliverable of the initiative, and it is what makes the "unmaintained" risk acceptable to sign off on.

Compatibility

Do not accept a green composer require as proof. Gate on:

  • Dependency resolution on the actual Laravel/PHP versions in production, with no "illuminate/support": "*" escape hatch.
  • Generated output validated by parsing the emitted JS in a headless run — a string with an apostrophe or </script> must not break the bundle.
  • Plural parity tests comparing trans_choice output to Lang.choice output across {0}, [1,19], {1} and default-branch cases, in the target locales.
  • Escaping tests with adversarial values committed to fixtures.

Sequencing

Phase Scope Effort Exit criteria
0 — Spike Compatibility, API surface confirmation, adversarial escaping test 2–3 days Documented go/no-go; facade and package identity resolved
1 — Boundary Internal exporter contract, Artisan command, deploy-time generation 3–5 days app:export-lang runs in CI; no runtime writes in prod
2 — Pilot One surface only — validation messages or global alerts 2–3 days Zero PHP/JS copy drift on that surface; cache-busting verified
3 — Rollout Inventory remaining hardcoded strings; allowlisted expansion group by group 1–2 weeks, incremental Every exported group has an owner and a reason to be public
4 — Normalize Replace package internals with owned implementation if fork was needed 2 days Package removable from composer.json without frontend change

Phase 3 is the schedule risk, not Phase 0. String inventory across a mature Blade codebase is unbounded until someone actually counts — force a count in Phase 0 and re-baseline the roadmap on it.

Operational Impact

Maintenance

Assume full ownership from day one. Assign a named maintainer, keep the vendored/forked code in-repo under version control, and add it to the dependency-review list so it is not orphaned when the original engineer rotates off. Do not track upstream; pin to a commit and treat divergence as expected. Republishing overwrites the JS stub — if any customization survives, it must live in our code, not in vendor/.

Support

On-call needs a one-page runbook, because the failure signature is opaque to anyone who has not seen it:

  • Lang is not defined → missing <script> include, empty generated file, or JS::put() never called on that route. Check the generated file on disk before debugging JavaScript.
  • Copy is stale → cache-busting query string, CDN TTL, or artifact not regenerated in the last deploy.
  • Copy is wrong in one locale → locale active at generation time, or a group missing from the allowlist.

Publish this triage tree; it converts a recurring 30-minute investigation into a 2-minute check.

Scaling

  • Payload size. Emitting a full locale on every page is fine at dozens of keys and wasteful at thousands. Set a budget — e.g. <50 KB gzipped per locale — and measure it in CI. Exceeding it is the trigger to move to per-route or lazy-loaded bundles.
  • Localization breadth. Adding a locale becomes "add a lang/de directory" plus a regeneration step — cheap, and the main strategic payoff. But per-user locale switching does not scale on this design without per-locale artifacts; if the roadmap includes user-selectable language, that requirement must be surfaced now, not discovered in Phase 3.
  • Deploy frequency. Deploy-time generation couples string changes to deploys. That is desirable for engineering-owned copy and actively hostile to a translator workflow. If marketing or a translation vendor needs to ship copy independently, that is a platform decision, not a patch.

Failure modes

  • Read-only or ephemeral filesystem → silent no-op, untranslated UI in production only. Highest-likelihood production incident; eliminated by Phase 1.
  • Concurrent regeneration → truncated or mixed-content locale file. Eliminated by build-artifact generation.
  • Escaping failure → JS syntax error breaking all client-side scripts on the page, or an XSS vector. Gate in Phase 0.
  • Over-broad export → internal messaging and admin keys publicly readable. Gate by allowlist discipline; review the generated artifact in code review.
  • Pluralization divergence → wrong plural forms in non-English locales, reported as a translation bug rather than a code bug. Gate with parity tests.

Ramp-up

  • Engineering: under a day, once the boundary exists. Without the boundary, expect every string change to require reading package internals.
  • Documentation to produce: the exporter contract, the runbook, the allowlist policy ("what may be exported"), and the cache-busting convention. Four short docs; skip them and the pattern will be re-implemented badly by the next team.
  • Acceptance criteria for the initiative: zero duplicated user-facing strings on the pilot surface; generated artifact under budget; parity tests green across target locales; app:export-lang runs in CI; no runtime writes to public/ in production; package removable without frontend change.
  • Metrics to report upward: locales supported, count of hardcoded strings remaining, artifact size per locale, and time-to-add-a-locale. The last one is the number that justifies the work — it should drop from an engineering project to a content exercise, and it is the claim executives will hold you to.
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.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr