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

pmochine/laravel-tongue

Laravel Tongue is a lightweight localization package for Laravel that simplifies multilingual routes and language switching. Define translated URLs, detect and persist the visitor's locale, and serve localized content with minimal configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Laravel-Tongue is a localization/routing package that sits between Laravel's router and the application's URL strategy. The 6.1.0 release materially changes its architectural posture: dialect()->localizedRoutes() moves translated route registration from a runtime concern into a declarative, boot-time registration, which is what makes the route table serializable. That is the difference between "works in a dev environment" and "works behind route:cache and Laravel Octane." For any Laravel service that deploys with cached routes and/or runs on Octane — now the default posture for most production Laravel estates — prior versions were effectively disqualified. This release removes that disqualifier.

Integration feasibility. The public surface is small and framework-idiomatic: a dialect() helper, two middleware (detects-tongue, speaks-tongue), and a redirect() method with an optional status. There is no persistence layer, no queue integration, no external service dependency. The main integration surface is middleware ordering, which is a configuration concern rather than a code concern — cheap to adopt, cheap to reverse. The redirect() status-code argument is a small but useful escape hatch for teams that need 301/308 semantics for permanent locale canonicalization rather than the default behavior.

Technical risk. Three areas need scrutiny:

  1. Middleware reordering. Moving detects-tongue and speaks-tongue ahead of SubstituteBindings is listed under "Changed," not "Breaking," but it is behaviorally significant. Route model binding will now resolve translated slugs, and speaks-tongue will redirect before a failed binding can 404. Any application with custom binding logic, custom route keys, or middleware that previously sat between detection and binding will see different runtime behavior. This is the highest-risk item in the release and the one most likely to be under-tested by the package's own suite relative to a bespoke host app.
  2. Redirect loops. speaks-tongue redirecting to "the path of the current locale" introduces a class of failure where detection and translation disagree — missing translation for a locale, a locale whose route was not registered, or a misconfigured default locale. Loop protection is not described in the notes and must be verified.
  3. 307 semantics. Preserving method and body for form requests is the correct choice for non-GET verbs, but it means POSTs to untranslated paths now round-trip data through a redirect. Clients that don't re-send bodies on 307, CDNs that normalize redirects, and API consumers expecting no redirects are all exposed. This needs an explicit decision about which route groups are allowed to redirect at all.

Key questions.

  • What Laravel and PHP versions are supported in the 6.1 constraint, and does the package handle Laravel 11/12 middleware registration (bootstrap/app.php) as well as the legacy HTTP Kernel?
  • Does localizedRoutes() require unique route names per locale, and if so what naming convention does it impose? Route-name collisions are a common failure when multiplying routes by locale.
  • Is there loop detection in speaks-tongue when a translation is missing for the detected locale?
  • What is the measurable cost of route:cache and route matching at realistic scale (e.g., 200 routes × 12 locales)?
  • Are translated routes registered during route:cache in a way that is stable across builds (deterministic ordering), or can cache artifacts drift between deploys?

Integration Approach

Stack fit. Fits any Laravel app with a multi-locale URL strategy — subdomain (fr.example.com/bienvenue) or path-prefix — that currently has no clean story for cached or Octane-served translated routes. Poor fit for apps that deliberately keep locale in session/header only, and for headless/API services where redirect-on-locale is the wrong contract.

Migration path. Treat this as a two-step adoption, not one:

  1. Upgrade to ^6.1 and do not enable localizedRoutes() yet. Confirm the middleware reordering doesn't change existing behavior — specifically, run the existing binding and 404 test suite, because that's where the ordering change will surface.
  2. Move route groups onto localizedRoutes() incrementally, starting with a low-traffic locale-partitioned group, then expanding. Keep the old dynamic registration path in place for groups not yet migrated so the rollout is per-route-group rather than big-bang.

Compatibility. Two hard gates before merge: php artisan route:cache must succeed and the cached app must serve every locale correctly, and the Octane worker must survive octane:reload with translated routes intact. Add both to CI — a route-cache smoke test is the single highest-value guardrail for this package.

Sequencing.

  1. Pin ^6.1, run full suite, diff middleware priority.
  2. Add route-cache + Octane smoke tests to CI.
  3. Adopt localizedRoutes() per route group behind a config flag.
  4. Decide and document redirect policy: which verbs/groups get speaks-tongue, and which status code (default vs. explicit 301/308 via redirect()).
  5. Only then retire legacy translated-route registration.

Operational Impact

Maintenance. Low ongoing code maintenance — the package is a thin layer — but the configuration surface (middleware order, locale list, route registration) becomes load-bearing. Adding a locale is now a deploy-time event that rebuilds the route cache and requires an Octane reload; that must be documented as a runbook step, not discovered during a release.

Support. Expect support load concentrated in two buckets: "redirect loop after adding a locale" and "404 after deploy because route cache was stale." Both are preventable with a documented deploy checklist and a post-deploy smoke check hitting one translated URL per locale. Translated-slug correctness also becomes a content-ops dependency — missing translations now manifest as redirects or binding failures rather than a soft fallback.

Scaling. Route count scales linearly with locale count. A 250-route app at 12 locales becomes ~3,000 route entries in the cached table, affecting cold-start memory, route:cache artifact size, and route-match time. This is generally acceptable but should be measured before committing to a large locale set, and it argues for keeping API routes out of the localized set entirely. Octane amplifies the benefit (routes boot once) while also amplifying any nondeterminism in registration.

Failure modes.

  • Stale route cache after locale or slug change → wholesale 404s or wrong-locale redirects.
  • Redirect loop when a locale's translation is absent.
  • 307 on POST with a client that drops the body → silent data loss on form submissions.
  • Binding resolves against translated slug but controller expects canonical key → null model / 404.
  • SEO regression: 307 is non-cacheable and non-permanent, so locale canonicalization may be recrawled repeatedly; needs deliberate 301/308 policy plus hreflang review.

Ramp-up. Modest for a mid-level Laravel developer — the API is small — but the conceptual load sits in middleware priority and route caching, which are exactly the areas many Laravel developers have never had to reason about. Budget half a day of team orientation covering: how localizedRoutes() registration interacts with route:cache, why middleware order matters for binding, and the redirect contract. Add one owner for the locale/redirect policy so SEO and product decisions don't drift from the technical implementation.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle