This episode is for members only

Sign up to access "Translations with Laravel and Inertia" right now.

Get started
Already a member? Sign in to continue
06. Setting the locale through Middleware


Technically, now that we have our dropdown hitting that end point to set that session, we have that value available. But the problem is for every single request we're now making, we're just, of course, defaulting to the default locale, which is English. So we're going to go ahead and create out some middleware in here, which will, for every request, set the correct
language. And then we can actually use that to translate stuff. So we're going to go ahead and make out some middleware, and we're just going to call this set language, like so. And let's first of all go ahead and register this middleware, because it's really important where we actually place this. So we're going to head over to our kernel under HTTP. Let's do this just for web
to keep things simple. Now, the really important thing here is we're going to be accessing sessions within that middleware. We need to boot up or start our sessions before we try and access session data, or it's just not going to work. But we need to do this before handle inertial requests, because we need that information to be available in there. So we're going to place
this middleware directly after start session. So we know that we have sessions available, but this comes before we access any of this information within handle inertial requests. So we're going to go ahead and add in the set language middleware directly into here. You can put the full qualified namespace in there, or just import it at the top.
Doesn't really matter. And we're good to go. So we're going to go ahead and open up the set language middleware. What do we need to do in here? Well, we need to use the app helper, and we need to set the locale. We've already looked at the get locale method. This time, though, we need to set it. Let's just do this manually for now, and then we'll do that based on the data that we have from
our session. And if I give the page a refresh, notice, sure enough, we are now translating, or not quite translating at the moment, but we will be to German. And of course, we can change that back to English here. So for every request, this is just setting the locale to a value that we have stored somewhere. And we know where we've stored this. We've stored this in a session.
So we're going to fill this in to grab it from that session. And again, we're going to use our enum as a kind of means of validation to make sure that we're not setting a locale that just doesn't exist. So in here, we're going to go ahead and again use our enum, and we're going to say try from. Now in here, we want to grab the value from the session. So we're going to say get and then
language. Now with our session get function, we can actually provide a default in here. So the default is going to be from our config and the default app locale. And then at the end of this, we want to grab the value. So let's go ahead and grab the value from that enum, which is of course going to be en, de, whatever we choose. So that's pretty much
what we need to do now. So if I head over and give this a refresh, it's currently set to German. Let's set this back to English and give this a refresh. It stays at English because that session now contains English. Again, back to German, give the page a refresh. It stays at German. So really with just a couple of lines placed both in the middleware and that controller,
we're now able to set the language that we want and persist it through our middleware. Finishing up, we're going to create a test, a unit test for our middleware, just to make sure that we know that this is working. So let's go and create out another test here. So we're going to say PHP artisan pest and test, and this will be a unit test, but let's call this set language
test, and let's create that as a unit test. So let's open up set language test and fill this in. So let's change this over to it and say sets the chosen locale, and that will be, of course, from our session. Now we're going to see a slight problem with this test, the way that this gets set up, and I'll show you why that is in the way that pest is set up by default. Let's go ahead
and just write this test out and just see what happens when we invoke our middleware. So I'm going to do this kind of all on one line. We're going to new up our set language middleware. Of course, you can assign that to a variable if you want to, but what we can do with this is just handle this middleware immediately, which will, of course, run it, and then we can just see what
happens. So in here, when we handle middleware, notice that we need a request and then a closure. So we're going to go ahead and just new up a request here from Illuminate and HTTP, and then in here we have a closure which contains our request inside of here. So in here, we can do anything we can assert in here, but the main thing that we need to do here is return a new response
because this requires that a new response object is returned. So all we're doing at the moment in this test is just invoking our middleware. That's it. We're not making any assertions. Let's run it and just see what happens. So let's say pest tests and unit and set language test. Okay, so let's have a look at what is happening here, what error we've got. It's just a syntax error again. Let's fix that
up, rerun it, and let's have a look here. Okay, so this is an interesting error that you'll probably find when you are using app-specific functionality within your unit tests specifically, and that is that it can't find this set locale method over on our container. Why is that? Why can't inside of our set language our test recognize that we're trying to do this? Well, that is just because of the way
that pest is set up with the test case that it extends by default. So if we go ahead and open up our pest.php file under test, you'll notice that this uses our test case which you'll find within standard php unit tests within Laravel. It will go ahead and extend or use the test case in here and refresh database, but this is only done in our feature test. Test case, if we just open this up,
creates up our application and boots up the framework so we have all of that functionality that we need to do things like access our locale and set our locale, but these are only being done in feature tests at the moment. Now rather than do this for every single unit test, we could do this and it would work. We're not going to do that because we might have other unit tests that just
don't use this functionality and that's really going to slow our tests down. So what we're going to do is we're going to specifically in our set language test use that test case. So let's go ahead and say use test case like so, and that should work. That will boot the framework up for us and now our middleware should then be allowed to run. So let's run set language test. Sure enough
now it runs with no errors, we just have a risky test because we're not performing any assertions. So now what we can do within this test is first of all set the locale that we expect to be set and then just expect it to be set. So we're going to say session put and remember this is the functionality that would exist within that controller that we've already built. So we're
going to set the language to German and then either within our handle method or outside of it, we're going to go ahead and expect the locale of our app to be de. That's pretty much what we need to do. So set this somewhere which we know exists within that controller that we've built when we switch the language, but then when this middleware runs we want to expect that when it does run
the locale is set to the one that's within that session. Now we already know this works because we've tested it on the client side, but this will just verify that this continues to work. Let's rerun our test, sure enough we get green. Just to finish up I'm going to run all of our tests just to make sure that nothing is relying on anything else and all of our tests here now look good.
9 episodes 57 mins


Localisation is a breeze in Laravel applications, but what happens when you need to bring this to the client-side? Turns out in Inertia, it's pretty simple.

In this course, we'll build a language switcher, share translations with the client, and build a simple translation helper for Vue to use directly in templates. We'll also cover caching translations to keep things running smoothly.

The best part? With the magic of reactivity, we'll be able to switch languages without any page refresh, and see everything instantly translated.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.