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

Loki Laravel Package

laravelista/loki

Laravelista Loki is a Laravel logging driver that ships your application logs to Grafana Loki, the log aggregation system. Configure a Loki channel in config/logging.php and each log entry is pushed to Loki with labels, ready for querying and visualization in Grafana dashboards.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package via Composer and publish its config:

composer require laravelista/loki
php artisan vendor:publish --provider="Laravelista\Loki\LokiServiceProvider"

This drops config/loki.php into your app. The two things you actually need to touch there:

  • supported — the whitelist of locales your app ships (e.g. ['en', 'hr']). Anything not in here should be rejected by your switcher.
  • default — the fallback locale when nothing else is set.

Register the middleware alias in app/Http/Kernel.php (under $routeMiddleware) so you can attach it to the web group:

'loki' => \Laravelista\Loki\Middleware\Loki::class,

Where to look first: vendor/laravelista/loki/config/loki.php and the Loki facade class — the surface area is small (getCurrentLocale, setLocale, getSupportedLocales, isCurrentLocale, getLocalizedURL-style helpers). Read those two files before wiring anything up; the whole package is basically a locale store + middleware.

First use case: build a locale switcher in your navbar, persist the choice in the session, and have the middleware apply it on subsequent requests. That's the "hello world" of Loki and covers 80% of real usage.

Implementation Patterns

Locale persistence via session. The core pattern is: user hits POST /locale/{locale}, you validate against Loki::getSupportedLocales(), call Loki::setLocale($locale) (which the package persists), then redirect back. The middleware reads that session value at the top of the request and applies it via App::setLocale().

Route::post('locale/{locale}', function ($locale) {
    abort_unless(in_array($locale, Loki::getSupportedLocales()), 404);
    Loki::setLocale($locale);
    return back();
})->name('locale.switch');

Middleware placement. Attach loki to the web group after StartSession, otherwise there's no session to read from. If you're doing per-route locale switching (e.g. /{locale}/posts), put it on the route group and read the segment into Loki::setLocale() in a small custom middleware that runs before Loki.

Locale switcher component. Pull the current locale once via a view composer or View::share and render a dropdown:

View::composer('*', function ($view) {
    $view->with('locales', Loki::getSupportedLocales());
    $view->with('current', Loki::getCurrentLocale());
});

Then in Blade, loop $locales, mark $current as active, and post to route('locale.switch', $code). Keep it a POST — a GET that mutates session state will get cached by proxies and cause "why is my locale randomly English" bugs.

Detecting from browser (Accept-Language). On first visit (no session key yet), parse $request->getPreferredLanguage(Loki::getSupportedLocales()) and hand the result to Loki::setLocale(). Do this in a listener/middleware before Loki, or the package will just fall back to default on every first page load. Ordering matters: detect → persist → apply.

Localized route URLs. If you need /{locale}/... prefixes, don't fight Loki — wrap your routes in a group with a prefix and set the locale from $request->route('locale'). Loki manages which locale is active; Laravel's route prefixing handles the URL shape. Keep them decoupled so you can later switch to subdomains without rewriting the package integration.

Testing. Freeze locale in setUp():

protected function setUp(): void
{
    parent::setUp();
    config(['loki.default' => 'en', 'loki.supported' => ['en', 'hr']]);
}

Then assert app()->getLocale() after hitting a switching route.

Gotchas and Tips

This package is stale — vet before you commit. Last release was Feb 2020, which predates Laravel 8+. Check composer.json constraints against your Laravel version; on Laravel 9+/10+ you'll likely need --ignore-platform-reqs or a fork. The API is simple enough that reimplementing it in ~40 lines of middleware is often the safer call than carrying a dead dependency.

Config cache bites. If you add a locale to config/loki.php and it doesn't take effect, you forgot php artisan config:cache (or config:clear in dev). Symptom: getSupportedLocales() returns the old array.

Never trust the incoming locale string. Always whitelist against getSupportedLocales() before calling setLocale(), otherwise a crafted ?locale=../../etc or an unsupported code ends up in the session and can leak into Lang::get() lookups (silent fallback, confusing missing-translation bugs). The package does not validate for you.

Session ordering is the #1 support ticket. If getCurrentLocale() returns the default on every request despite a set session, the middleware is running before StartSession, or it's not in the web group at all. Confirm with php artisan route:list -v.

Locale ≠ translation files present. Loki sets app()->getLocale(); it does not create resources/lang/{locale} directories or validate that keys exist. Missing files fall back to the fallback locale silently — you'll only notice when a page renders in English on /hr/. Add a test that asserts a known key in each supported locale.

Extension points are thin. The cleanest customization is to publish the config and, if you need different detection (cookie vs. session vs. header), write your own small middleware and use Loki purely as the locale accessor. Avoid editing vendor files — there's no event/hook system to speak of.

Facade vs. helper. Loki::getCurrentLocale() is just app()->getLocale() with extra steps in most cases. If you're only reading the locale, use Laravel's native App::getLocale() and reserve Loki for the persistence/switching behavior — that keeps your code portable if you drop the package later.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
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