0

Right now I need to set my locale based on the locale set in the URL in order for my app to work properly. I am using translated slugs as well and if the locale is not set before the routes are loaded, it will always default back to the default locale. Therefore I need to set the locale in for example my RouteServiceProvider.

For that I have the following in the boot method of my RouteServiceProdiver right now:

if (in_array(request()->segment(1), ['ca', 'en', 'es', 'nl']))
{
    request()->segment(1)
        ? app()->setLocale(request()->segment(1))
        : app()->setLocale('en');
}

So currently I have four languages that I can use. All of my URLs look like this:

https://mywebsite.com/en/users
https://mywebsite.com/nl/gebruikers

So the locale is always set in segment(1) of the URL.

In my LocaleMiddleware I have the following:

if (Auth::check())
{
    app()->setLocale($request->user()->getLocale());
}

$request->user()->getLocale() just returns en, nl and so on.

The Problem:

Sometimes, for whatever reason, if the current locale is set to nl, the URL changes to en.

So the URL I am on right now is:

https://mywebsite.com/nl/gebruikers

But I click on refresh, or back, or something along those lines, and suddenly the URL has changed to:

https://mywebsite.com/en/users

Of course next to the fact I do not like the look of this, it also poses a problem next to the cosmetic problem of how the URL looks. If I go to any model to view the details, I get a 404. Example: My locale is set to dutch right now but in the URL it has been set to en for whatever reason. The URL looks like this:

https://mywebsite.com/en/categories/slug-en/show

But in reality it should look for the model with a slug of slug-nl. So it does not find it and throws the error. This is because the locale is actually set to nl for this user but the route, and slug, is set to the en locale.

TL;DR:

I can set the user locale perfectly using a middleware and everything works as it should. But for specific reasons I need to set my locale before the routes are loaded and this needs to be done in for example my RouteServiceProvider or AppServiceProvider.

If I could somehow have access to the logged in user or to the session in one of the Providers, then I would have no issue. But since this is not possible, I am stuck.

Hardist
  • 2,098
  • 11
  • 49
  • 85
  • Have you checked https://stackoverflow.com/q/60415715/3348994 it looks similar question – Leena Patel Nov 09 '22 at 11:00
  • Not the same thing. And for now I have solved it by setting my locale based on the URL parameter in my RouteServiceProvider but still I do not understand why it does not work with a middleware. – Hardist Nov 09 '22 at 13:11
  • why retrieve `request()->segment(1)` when the locale part is a part of segment 2 ? – Chinh Nguyen Jan 06 '23 at 04:37
  • My bad maybe for explaining it wrong, but the `segment(1)` is in this case correct. – Hardist Jan 06 '23 at 08:55
  • To get a full answer you need to provide some more information. Are you using laravel's model binding? What do you want to do/show if a user with locale set to en goes to /es/test-nl ? Where do you redirect the user after login? Imho, the most relevant pattern should be always /lang/slug-of-lang and maybe /slug-of-default-lang-from-config. This is to prevent confusion by having different content for different urls for different users. To do this, just skip the user related stuff when setting the locale and make sure url generation is based on settings. es locale -> /es/ on links. – Idea to Code Jan 06 '23 at 18:38
  • So it seems I did fix the initial issue, hence my edited answer below. If anyone wishes gain the bounty please post an answer so I can reward someone :) – Hardist Jan 07 '23 at 12:08

1 Answers1

0

Edit:

So the previous solution to this was the below answer. But I have removed this to do some more testing and it seems the initial problem has been solved and I do not need to do the below anymore. Which fixes this whole issue.

Initial answer:

I have solved this by setting my locale in my RouteServiceProvider, in the boot method:

request()->segment(1)
    ? app()->setLocale(request()->segment(1))
    : app()->setLocale('en');
Hardist
  • 2,098
  • 11
  • 49
  • 85