Download the PHP package edulazaro/laralang without Composer

On this page you can find all versions of the php package edulazaro/laralang. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laralang

Laralang for Laravel

Tests Latest Stable Version Total Downloads PHP Version License

Introduction

Laralang is a Laravel package that allows you to create localized routes for different languages. By defining routes with language support, you can easily manage multilingual applications.

With Laralang, you can define a route for each language, and the package will automatically generate routes for the specified locales. It provides an efficient way to handle localized URIs and ensures that the URL structure is properly mapped to the language-specific paths.

Features

Requirements

Every combination of those is covered by the test suite on each push, and once a week so a new release that breaks the package shows up here first.

For Laravel 10 support use Laralang ^1.5.

Migration

Coming from another localization package? There is a migration guide for each one:

Already on Laralang 1.x? See UPGRADING.md for the 1.x to 2.0 guide.

Installation

Execute the following command in your Laravel root project directory:

Getting started

This will generate routes for /dashboard in English and /es/panel in Spanish:

You can add any middleware as usual:

Configuration

Publish the Laralang configuration using this command

If it does not work, then try:

This will generate the locales.php file in the config folder. It defines the languages your application supports, their URL prefixes and how the package behaves around them. Below is a breakdown of each section.

Supported Locales

The locales array defines the languages that your application supports. You can list multiple languages here, and the system will handle the routes accordingly.

Add or remove any locales as per your application's requirements.

Locale Prefixes

The prefixes array allows you to specify custom URL prefixes for each locale. When a locale has a prefix defined, URLs in that locale will have the prefix as part of the path. You do not need to specify all prefixes, as by default the locale name will be used as a prefix except for the default language. However, if you want to customize the prefixes:

The default language never carries a prefix. It is the one in config('app.locale'), not the first entry of the locales array, so with APP_LOCALE=es it is Spanish that lives at the root and English that gets prefixed. SetRouteLocale enforces it too: a first segment matching the default locale is redirected with a 301 to the same URL without it, so there is a single canonical URL per page.

The rule is short: a value is the literal prefix, and without one the locale code is used. A missing key, null and an empty string all count as no value.

Value Default language Any other language
key missing, null or '' no prefix its own code, /fr
'anything' that literal, /anything that literal, /anything

Only the default language can live at the root, so two locales can never end up sharing the same URLs.

Prefixing every language

By default the language in config('app.locale') lives at the root, and a URL that repeats its prefix is redirected there with a 301, so each page has a single canonical URL.

Give the default language a prefix of its own and that stops: every language gets one, and nothing lives at the root.

Since no route is registered at / any more, turn the localized fallback on so the root has somewhere to go:

It sends the visitor to their own language, taken from their stored choice and then from Accept-Language, falling back to the default. That redirect is a 302 with Vary: Accept-Language, never a 301, because the destination depends on who is asking and a permanent one would be cached and pin a single language for everyone behind it.

Decide the prefixes before going live

Everything else the package redirects is a 301, which is the right status because the destination depends only on the path. But permanent means permanent: browsers and CDNs cache it, and a cached 301 is never re-checked. The client stops asking.

Those redirects are computed from prefixes and the order of locales, so changing either after the site is public leaves old clients following redirects to URLs that no longer exist.

The painful case is exactly this section. A site runs with English at the root, so /en/about has been answering 301 to /about for months. You then prefix every language, and /en/about becomes the canonical URL. A returning visitor requests it, their browser applies the cached redirect without asking, and lands on /about, which no longer exists. With the localized fallback on it is worse than a 404: /about is rescued back to /en/about, the cached redirect fires again, and the browser gives up with a redirect loop.

A 301 that is already out there cannot be revoked, so treat the shape of your URLs as a decision to make before launch. If you have to change it anyway, consider turning the fallback off during the transition, so a visitor with a stale redirect gets a plain 404 instead of a loop.

What you can bound is how long that lasts. Every permanent redirect the package emits carries an explicit lifetime, so a returning visitor holds a stale one for at most that long instead of forever.

Redirect cache lifetime

Sets the Cache-Control: max-age of the permanent redirects, the one that strips a redundant default locale prefix and the fallback rescue. It exists for the reason described just above: those destinations are computed from prefixes and the order of locales, and without an explicit lifetime a browser caches them heuristically, in practice for as long as it feels like.

A day is a good default while your URLs are still moving. Raise it once they are settled, since the redirect is stable and revalidating costs a request. The 302 at the root is never cached: it carries no-store, because its destination depends on the visitor.

How to Register Localized Routes

Use LocalizedRoute::get(), LocalizedRoute::post(), LocalizedRoute::put(), LocalizedRoute::patch(), LocalizedRoute::delete(), LocalizedRoute::options(), LocalizedRoute::any() or LocalizedRoute::match(), the same way you would use Laravel's regular routes:

Assuming en is your default locale, those two calls register four routes:

Method URL Route name
GET /profile en.profile
GET /es/perfil es.profile
POST /update-profile en.update-profile
POST /es/actualizar-perfil es.update-profile

This is how it works:

Matching several methods

match() takes the list of HTTP methods as its first parameter, and any() registers the route for all of them:

any() still registers one route per locale, and each of them answers every verb (GET, HEAD, POST, PUT, PATCH, DELETE and OPTIONS), exactly like Laravel's Route::any(). The list comes from Laravel itself, so it stays in sync if a verb is ever added.

Keep in mind the usual caveats of any(): a route registered with it shadows a later route for the same URI, and it answers 200 to verbs that would otherwise return 405.

Inside a route group

The locale prefix always goes first, before any prefix coming from the group:

URL Route name
/admin/dashboard en.admin.dashboard
/fr/admin/dashboard fr.admin.dashboard
/es/admin/panel es.admin.dashboard

Note that fr reuses dashboard because it was listed without a translation, while es uses its own panel. Group middleware, name prefixes and everything else you chain on the group keep working as usual.

Localized Resources

LocalizedResource registers a Laravel resource once per locale. Laravel's own resource registrar builds the routes, so only(), except(), names(), middleware(), shallow() and scoped() keep working exactly as you know them, applied to every locale at once.

URL Route name
/photos en.photos.index
/photos/create en.photos.create
/photos/{photo} en.photos.show
/es/fotos es.photos.index
/es/fotos/create es.photos.create
/es/fotos/{photo} es.photos.show

Two things are deliberate here. The route names use the base resource name in every locale, so route('photos.index') resolves to the current language like any other localized route. And the route parameter is {photo} in every locale, derived from the base name too, so a single show(Photo $photo) controller signature keeps working no matter which language resolved the URL.

The first parameter is the base name, used for names and parameters. The second lists the locales, exactly like the other methods. The third is the resource controller.

Translating create and edit

Pass an array instead of a string to give a locale its own create and edit segments:

URL Route name
/photos/create en.photos.create
/photos/{photo}/edit en.photos.edit
/es/fotos/crear es.photos.create
/es/fotos/{photo}/editar es.photos.edit

Without the verbs key those two segments stay in English for every locale.

API resources

LocalizedResource::api() registers the same resource without the create and edit routes:

Localizing an API is rarely what you want, since its URLs are consumed by machines and the language is usually negotiated with the Accept-Language header. It is here for APIs meant to be browsed, not for integration endpoints.

Chaining options

Anything you would chain on Route::resource() is forwarded to every locale:

The LocalizedRoute bridge

If you prefer the spelling that mirrors Laravel, LocalizedRoute::resource() and LocalizedRoute::apiResource() do exactly the same, delegating to LocalizedResource:

How to Use Localized Routes in Views

To generate URLs for your localized routes, you can use the route() helper as usual:

However if you run just route('dashboard') it will also work, and it will redirect to the route named dashboard of the current locale.

Ziggy

If Ziggy 2 is installed, Laralang replaces its Blade route generator so the routes of the current locale are also published under their unprefixed name. That way route('dashboard') behaves in JavaScript exactly like it does in PHP, while route('es.dashboard') keeps working too.

It is detected automatically and needs no configuration. Ziggy 1 is not supported, since it reached its last release before Laravel 11, which is the minimum this package requires.

A route registered directly under the unprefixed name, for example a plain Route::get(...)->name('dashboard'), is never overwritten by the alias.

Generating Alternate URLs

For language switchers, hreflang tags in the <head> for SEO, multi-locale sitemaps and canonical URL switching, Laralang exposes Laralang::alternates(). It returns a map of every configured locale to the URL of the current route in that locale, without the usual hand-rolled App::setLocale() swapping.

Typical hreflang usage inside a Blade <head>:

A typical language switcher:

The signature is:

Behaviour notes:

A global helper is also available if you prefer to avoid the facade import:

Using routeIs() with localized routes

Because LocalizedRoute registers one route per locale with names like en.services, es.services and fr.services, a plain routeIs('services') check used to silently never match, forcing users to write routeIs('*.services') in navigation active-state helpers.

Laralang now ships a thin EduLazaro\Laralang\Routing\Route subclass that overrides named() for LocalizedRoute instances only. Plain Route::get() routes keep Laravel's default behaviour untouched.

The matching rules are:

The previous routeIs('*.services') workaround still works.

Localized Fallback

A URL is often shared or linked without its locale prefix, or with the wrong one. /servicios reaches an application that is running in English, /es/services reaches one that expects the Spanish path. Both are a 404 by default, and both are a page you already have.

Turn the rescue on in the config:

From then on, a URL that matches no route but does exist under another locale is redirected there with a 301:

Requested Rescued to
/servicios /es/servicios
/fr/servicios /es/servicios
/es/services /services
/propiedad/piso-centro /es/propiedad/piso-centro

Route parameters are honoured, since the candidate URL is handed to the router instead of being compared as a string, and the query string travels along untouched.

Anything that cannot be rescued keeps returning the 404 it deserves, and the check only ever runs once the router has already failed, so normal traffic costs nothing.

Which locale wins

Locales are tried with the default one first, then in the order of locales.locales. That way the destination depends only on the path and never on the visitor, which is what makes a permanent redirect safe: a 301 gets cached by browsers and CDNs, so a destination that changed with the visitor's language would pin one language for everyone behind the cache.

If your application has its own fallback

Laravel runs the first fallback route registered, so leave the config off and place the rescue yourself, before yours:

When the rescue finds nothing it throws the usual NotFoundHttpException, so your own error handling still takes over.

Note that Laravel registers fallback routes for GET only, which is what you want here: a redirect would drop the body of anything else.

Middleware

Laralang comes with several optional middlewares that you can apply depending on your needs. These middlewares help you control how the locale is detected and applied throughout your application.

You can assign these middlewares to your route groups just like any Laravel middleware. For most applications, you can simply use SetSmartLocale globally to cover all use cases.

For specific sections of your app, you can fine-tune and assign different middlewares to different route groups.

Idempotency

All locale middlewares are idempotent. Applying SetSmartLocale to a group and using LocalizedRoute (which auto-attaches SetRouteLocale per route) is safe: the first middleware to run resolves the locale and the rest become no-ops. Build whatever middleware stack you need without worrying about double execution or duplicate redirects.

If every route is created via LocalizedRoute, you do not need to add SetSmartLocale to your group, since SetRouteLocale is already injected per route. Add SetSmartLocale only when you have a mix of localized and plain routes and want the plain ones to inherit the session/browser locale.

SetRouteLocale

This middleware will detect the locale from the URL prefix and apply it.

If you have localized routes with prefixes (e.g., /es/dashboard), this middleware ensures the application locale matches the URL.

Visiting /es/panel sets the application locale to es before the controller runs, so __(), dates and anything else locale aware already use Spanish. Visiting /dashboard does the same for the default locale.

SetSessionLocale

This middleware applies the locale stored in the user session.

Useful for internal routes like dashboards or admin panels, where the locale is determined once and stored in the session.

These URLs never change, whatever the language. The locale comes from session('locale'), which the language switcher writes, so the panel stays in the language the user picked until they pick another one.

SetBrowserLocale

This middleware reads the locale from the browser's Accept-Language header only if no session locale is already set.

On first visit, it detects the preferred browser language and stores it in the session. Good for public routes to auto-detect a first-time visitor's language and store it for subsequent requests.

A visitor arriving with Accept-Language: es-ES gets / in Spanish on the very first request, and the choice is stored in the session so the rest of the visit stays in Spanish.

SetSmartLocale

This is the recommended "universal" middleware.

It combines all the previous strategies in this priority order:

If you want to apply localization globally without thinking about it, this middleware is for you.

/es/contacto runs in Spanish because of the prefix, and /dashboard, which has no prefix to read, falls back to the session and then to the browser language.

Author

Created by Edu Lazaro

License

Laralang is open-sourced software licensed under the MIT license.


All versions of laralang with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
laravel/framework Version >=11.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package edulazaro/laralang contains the following files

Loading the files please wait ...