PHPackages                             thinktomorrow/locale - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. thinktomorrow/locale

ActiveLibrary[Localization &amp; i18n](/categories/localization)

thinktomorrow/locale
====================

A Laravel package for route and domain based localization

5.0.2(3mo ago)27.5k↓30%[1 issues](https://github.com/thinktomorrow/locale/issues)[11 PRs](https://github.com/thinktomorrow/locale/pulls)MITPHPPHP &gt;=8.2CI failing

Since Dec 24Pushed 3mo ago3 watchersCompare

[ Source](https://github.com/thinktomorrow/locale)[ Packagist](https://packagist.org/packages/thinktomorrow/locale)[ Docs](https://github.com/thinktomorrow/locale)[ RSS](/packages/thinktomorrow-locale/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (6)Versions (60)Used By (0)

locale
======

[](#locale)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2538dbb05c55885ee5b4df172a7ac2ddeae5f56598552ad6f0aa956eeb2fde28/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7468696e6b746f6d6f72726f772f6c6f63616c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/thinktomorrow/locale)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Quality Score](https://camo.githubusercontent.com/527360a443bc3e2be24831ac4bd5a492a17c8d20f1be20dbd1bb551318e70aec/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f7468696e6b746f6d6f72726f772f6c6f63616c652e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/thinktomorrow/locale)[![Total Downloads](https://camo.githubusercontent.com/7b15ea05099168d2e587a631151cb84b74ee79ca79f899fc75e2262ab05f320a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7468696e6b746f6d6f72726f772f6c6f63616c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/thinktomorrow/locale)

Requirements
------------

[](#requirements)

The package requires a php version of `8.2` or more. Laravel version `5.6.*` and upwards is supported.

Installation
------------

[](#installation)

The package can be installed via Composer.

```
$ composer require thinktomorrow/locale
```

The package service provider will be autodiscovered by laravel.

To publish the config file to `/config/thinktomorrow/locale.php`, run:

```
    php artisan vendor:publish --provider="Thinktomorrow\Locale\LocaleServiceProvider"
```

These are the config defaults:

Setup
-----

[](#setup)

Let's say you want to support two locales: nl and en, where nl is the default locale. Here's how you would configure this:

```
# config/thinktomorrow/locale.php

'locales' => [
        '*' => [
            'en' => 'en',
            '/'  => 'nl',
        ],
    ],
```

Some important things to note here:

- The key of each entry represents the uri segment whereas the value is the application locale.
- The \* acts as a wildcard group, which means any *host* will match. This is called the default *scope* but more on scopes later on.
- The default locale has a forward slash '/' as its key. This is a required item. It is the locale when no specific uri segment matches.

### Segments

[](#segments)

The package allows for two ways to identify the locale in a request url. Either via path segments or via the host. Let's take a moment to introduce these concepts. A locale segment is the uri path identifier of a specific locale. E.g. *example.com/nl* has *nl* as a locale segment since it identifies the locale in the given request uri.. This is the most common way of determining locales via the incoming request. This is also sufficient when your application only has to deal with one domain root.

The configuration for this is the most basic setup where you give a list of locales under the default scope, like the config example from above.

### Scopes

[](#scopes)

A scope is a higher level identifier for a group of locales. Generally, you can compare a scope with the host part of the request url. A scope bundles one or more of these segments together.

Let's say we want to allow *example.com* and *fr.example.com*, where the first host localises in nl and the latter in fr. We can provide the following configuration:

```
# config/thinktomorrow/locale.php

'locales' => [
        'fr.example.com' => 'fr',
        '*' => 'nl',
    ],
```

- If the scope detects only one locale, it can be entered as a string, instead of an array.
- The more specific scope should be placed first, because matching is performed from top to bottom.
- The default scope '\*' is always required and because of the *first match first serve* rule, should be placed at the bottom of the list.

If your application is visitable by only one domain root, which is the case for most apps, you are good to go with the default scope. All available application locales are grouped by so called scopes. Each scope has its own set \* of locales. A scope which can be compared with domains. Each scope \* could represent a domain and its supported locales. Each scope entry consists of a key as the \* pattern identifier and an array of locales. Matches are done from top to bottom so declare \* the more specific hosts above general ones.

Usage
-----

[](#usage)

To make your routes localized, place them inside a Route::group() with a following prefix:

```

    Route::group(['prefix' => localeRoutePrefix()],function(){

        // Routes registered within this group will be localized

    });

```

Generating a localized url
--------------------------

[](#generating-a-localized-url)

Localisation of your routes is done automatically when [named routes](https://laravel.com/docs/5.2/routing#named-routes) are being used. Creation of all named routes will be localized based on current locale. Quick non-obtrusive integration.

```
    route('pages.about'); // prints out http://example.com/en/about (if en is the active locale)
```

To create an url with a specific locale other than the active one, you can use the `Thinktomorrow\Locale\LocaleUrl` class.

```

    // Generate localized url from uri (resolves as laravel url() function)
    localeroute('about','en'); // http://example.com/en/about

    // Generate localized url from named route (resolves as laravel route() function)
    localeroute('pages.about','en'); // http://example.com/en/about

    // Add additional parameters as third parameter
    localeroute('products.show','en',['slug' => 'tablet'])); // http://example/en/products/tablet

```

**Note:** Passing the locale as 'lang' query parameter will force the locale *example.com/en/about?lang=nl* makes sure the request will deal with a 'nl' locale.

Configuration
-------------

[](#configuration)

- **locales**: Whitelist of locales available for usage inside your application. Basic usage:

    ```
        'locales' => [
            '*' => [
                'nl',
                'en',
            ]
        ],
    ```

    Multi-domain usage:

    ```
        'locales' => [
            'https://awesome-domain-nl.com' => [
                '/' => 'nl',
            ],
            'https://awesome-domain-en.com' => [
                '/' => 'en',
            ]
        ],
    ```

    Each multi-domain can have multiple locale as well: Multi-domain usage:

    ```
        'locales' => [
            'https://awesome-domain.com' => [
                'en'    => 'en',
                '/'     => 'nl',
            ]
        ],
    ```
- **hidden\_locale**: You can set one of the available locales as 'hidden' which means any request without a locale in its uri, should be localized as this hidden locale. For example if the hidden locale is 'nl' and the request uri is /foo/bar, this request is interpreted with the 'nl' locale. Note that this is best used for your main / default locale.
- **placeholder**: Explicit route placeholder for the locale. Must be used for the LocaleUrl::route()` method when multiple parameters need to be injected.

Locale API
----------

[](#locale-api)

#### Set a new locale for current request

[](#set-a-new-locale-for-current-request)

```
    Locale::set('en'); // Sets a new application locale and returns the locale slug
```

#### Get the current locale

[](#get-the-current-locale)

```
    Locale::get(); // returns the current locale e.g. 'en';

    // You can pass it a locale that will only be returned if it's a valid locale
    Locale::get('fr'); // returns 'fr' is fr is an accepted locale value
    Locale::get('foobar'); // ignores the invalid locale and returns the default locale
```

#### Get the locale slug to be used for url injection

[](#get-the-locale-slug-to-be-used-for-url-injection)

```
    Locale::getSlug(); // returns 'en' or null if the current locale is set to be hidden
```

#### Check if current locale is hidden

[](#check-if-current-locale-is-hidden)

```
    Locale::isHidden(); // checks current or passed locale and returns boolean
```

Testing
-------

[](#testing)

```
$ vendor/bin/phpunit
```

For more details check out our full documentation

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- Ben Cavens

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance69

Regular maintenance activity

Popularity26

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity90

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 90.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~82 days

Recently: every ~220 days

Total

46

Last Release

112d ago

Major Versions

1.4.1 → 2.0.12018-01-07

1.5 → 2.0.22018-04-19

2.5.3 → 3.0.02022-06-13

3.0.2 → 4.0.02024-04-22

4.0.0 → 5.0.02025-01-07

PHP version history (10 changes)0.0.1PHP &gt;=5.5.9

1.0.3PHP &gt;=5.5.9|&gt;=5.6|&gt;=7.0

1.4.0PHP &gt;=7.0

2.0.1PHP &gt;=7.1

1.5PHP 5.\*|7.\*

2.0.2PHP &gt;=7.1.3

2.3.0PHP &gt;=7.2

2.0.x-devPHP &gt;=7.3

2.5.0PHP &gt;=8.1

4.0.0PHP &gt;=8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/497668?v=4)[Ben Cavens](/maintainers/BenCavens)[@BenCavens](https://github.com/BenCavens)

---

Top Contributors

[![BenCavens](https://avatars.githubusercontent.com/u/497668?v=4)](https://github.com/BenCavens "BenCavens (207 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (16 commits)")[![yinx](https://avatars.githubusercontent.com/u/1022847?v=4)](https://github.com/yinx "yinx (5 commits)")

---

Tags

laravellocalelocalethinktomorrow

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/thinktomorrow-locale/health.svg)

```
[![Health](https://phpackages.com/badges/thinktomorrow-locale/health.svg)](https://phpackages.com/packages/thinktomorrow-locale)
```

###  Alternatives

[fightbulc/moment

Parse, validate, manipulate, and display dates in PHP w/ i18n support. Inspired by moment.js

9693.2M10](/packages/fightbulc-moment)[laravel-lang/locales

Basic functionality for working with localizations

134.5M12](/packages/laravel-lang-locales)[codezero/browser-locale

Get the most preferred locales from your visitor's browser.

161.4M13](/packages/codezero-browser-locale)[jrmajor/laravel-fluent

Fluent translations for Laravel

208.4k](/packages/jrmajor-laravel-fluent)[cariboufute/locale-route

A testable route package with localization for Laravel 5 to 12

206.7k](/packages/cariboufute-locale-route)[optimistdigital/nova-locale-manager

Laravel Nova tool to manage locales.

167.0k](/packages/optimistdigital-nova-locale-manager)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
