i18n in Next.js 14 (App Router) | next-intl

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
internationalization has never been this easy with nextjs for this I'm going to show you how you can use the next internationalization library to support multiple languages in your application so for a demonstration purposes I have this basic landing page we have this title we have this accelerate your progress we have this introductory paragraph and then some featured items and we also have this date here which says last updated January 5 2024 and finally we have the newsletter section so there are a couple of things to note here we are dynamically rendering these featured items so we will learn how to do that with this library and we're also rendering a date so we will see how we can use the ICU new standard to provide these formats all across every single language so I bootstrapped an application using the T3 stock so this is a next gs14 project we have the layout and the roote page here in the page we're rendering the product section and then the newsletter in the product section we have this array featured items which contains ccon type title and then description and then we dynamically render them here in this unordered list which is this one so at list item we get the icon we apply some classes and then we have this pan so again this is for each of these featured items and then we have this new date and then we use to local date string and then we do not Define the local and then we pass in these options so it's pretty much a medium format for the data and as for the newslet we just have some tags here so paragraph The Heading the label the bottom label and we have this extra information so nothing too fancy here so with this let's start implementing the internationalization so I'll come here over to the official page come here to up router and then they tell you to mpm install next Intel so I'll copy this and since I'm using yarn I'll say yarn add and then next Insel and once we have this we can move on so they tell you to use the setup so State the messages to be in source which is a folder and then you can add the Json file for the locals so let's do that I'll come here and here in the root I'll create a directory messages and then for now we're just going to have English so n. Json and we can start adding things here so we can say test this is a test and with this we now need to come here over to the next configuration file and add this with next Intel so I'll come here to the next. config.js and I'm going to say con next Intel config is equal to with next Intel and then we can say export default next in config and we pass in the base config so you can add things here that way you do not lose the base configuration that you provide to next year yes so having done on this we need to restart this server but before doing that let us finish installing this so we must create this file at the root of the source so i18n dots so I'll come here over to the source and then new file. Cs and then I'll just copy this and paste it here now here they are asserting this to be anything but I prefer to be more type save and not only this but they are strictly checking for these locals that means that if there's any local that extends from one of these base locals it is not going to work at least not from what I tested so you need to get the base one so what I mean is let's say we have English and Spanish and for Spanish you may have S or you may have S and then 419 etc for Mexico for us for Argentina the list is endless so to make sure that this one will be mapping over to whatever of these subl locals we can say const base local is equal to new Intel and this doesn't come from the library this is native to the language we can say local we pass in the local and then we can access the base name so as we can see returns a substring of the Local's string representation containing core information about this local that way we can now map to these ones in every single case so we can say if it doesn't include the base local we can return not found so now we can save this and we can move on to the fourth one so create the middleware so for this I'll come here over to the root so the source and then middle word. Cs and then we can say const next until middleware is equal to create middleware and we can say which locals we support So English and Spanish and then default local so like theault back if the user is coming in with another local that is sent either of these two or whichever you specify then we can and say F back to English and then for the middle word we must export theault a function which takes in the request which is next request and should respond with a next response and we simply return the invocation of this middleware so we pass in the request and it is going to use the headers for the language or the cookie that the libraries specifies internally so that cookie will be used for any subsequent requests which allows the user to change the local if they want to and then we can say export con config and we can say match only internationalized routes or path names and then matcher and it's pretty much the same one that they added there which is this one so we can copy this whole line hey it here and in this case it will be either Spanish or English so now we can save this middleware and let's move on to the fifth one so the local that was matched by the middleware is available via the local param this means that here you would access via sln or slash S or whichever other local that you specify so for that you need to use this path r out which should actually be in the root of the application so you can come here over to up and then say local which means that this route will accept a path and then we can move everything under this directory so with this we can now use the use translations hook and we should also specify the local here in the body so for that we can come here to the layout and we can say type props is equal to it takes children so react node and the params which is actually an object and local will be either English or Spanish now you may be wondering where does this local come from again from the middleware so it passes them down as properties so with this we can change this to be const R layout then then react. FC then we can get rid of this type definition and this will be an a function and then we can say export default the root layout and then we can add the props type here so Props and we must say const messages is equal to use messages so we import this Hook from usel and then here IND the language it should be the one that we get so harams and then local so local and then next inel client provider we pass in the messages so these ones right here and then we wrap all of the components so with this it should work let's try it out if I run this and then come here refresh there is an error cannot resolve messages and that is because messages are actually relative to this file so do slash then we come here to messages and then the local and we should also use the base local and then we can come back to the layout and we should actually wrap this within the children so with this if I hit save and then open this up we get a create context only works in client components I fix the error and that is we were importing use messages from The Base Library when it should be from next Intel instead so with that change if I save the file and then come back here as we can see it works as expected so we get sln so now let's try internationalizing this is so how can we access our files well for that we can come here to say the product section and then we can say const t is equal to use translations and we import that from the library and then we can pass in a a namespace the problem here is this is not typ safe whatsoever so if we were to invoke T we get no what complete which makes it very error prone so for that what you can do is come here to the root of your whole project and create a global. the which is declaration. TS file and then we can say type messages is equal to type off import and we come here over to the source and then to the messages and then Target every single file to extract the types and then we declare this interface which gets all of the messages by extending from these two so if you have more locals you would add them here that way you get a full type safety so with this we can also create an s. ajon file and then we can copy this paste it here and we can say Spanish and for this let us say English and with this if I save this and then come back here to the product section we now get an error saying well this key doesn't exist so if I hit control space I get all of the possible keys that there are in these files so we can get access to test which will return a string so with that we can for example come here to this paragraph I'll commend this out for the time being and then we can say t and then we pass in the key test hit save then come back here and as we can see we get English if I change it to S we get Spanish right away and in fact if I inspect element and then come here over to application and then to cookies as we can see it said its own cookie so next local and this is very important because we are able to change between different locals and so the library will remember your choice which is incredibly important for that user experience no application or website should ever force a local you should set the local based on where the user is so from the browser settings but if the user wants to change their local you should always give that option out so with this we can now go back to English and the cookie is now English this is all handled by the middle work internally so now let's internationalize this whole page so what I'm going to do is come here and come here to n. adjacent and we'll change this to product section so this will be the component and we have this one so we have the subheading so subheading I'll paste this we have the actual title which is going to be streamline your workflows and we're going to have these paragraph So what I'm going to do in instead of doing all of these manually I'll open up cursor which is an ID that integrates GPT 4 and I'll open up the chat and here in the chat I'll say add the remaining messages to the internationalized and adjacent file based on the product section component and then I can say at product section and then I can say t SX and this is going to automatically happen to the conversation the whole file and then I can say this file and then n. Json and if I hit enter it should do the work for us so we have subheading title description no team title No team description but I notice that I'm using GPT 3.5 instead of four so let me change that and if I hit enter we now get a better result so we can copy this file and then we can paste the whole content here but now we need the Spanish translation so let's do the same translate this n. Jon file to Spanish in its respective s. Json file and so with this I can open up this file and then once this is is done I can copy the result paste it here and now they are synchronized so how about we use them I'll open up Webster and then we can say here if I hit control space as we can see we get all of the messages that we have in the Json files so we can access the nested ones by using the dot so product section. features do database multiple but since we know this component is only for the product section we do not need the other messages so for that we can come here and specify the namespace to be that of product section and so with this we can come here and we can say and let me actually see here so subheading and we can get rid of this and then this will be the title or the heading not sure I think it's title and then we have the description so T description and we can do that with the remaining ones and I just noticed that it did not translate this paragraph So let's skip that for now and actually do the array so how can we render this array using these ones now there's something important with this library and pretty much any other internationalization Library and that is you cannot use arrays which is quite the limitation but for that you should use objects so key value Pur so as we can see we have the features push to deploy SSL certificates and then database backups so for that what I'm going to do is copy this array and then I'll move it down here and then we can say t add and then features and then this will be the instant update so push to deploy which is push to deploy like this so title and then description will be description pretty straightforward then SSL certificates this will be certificates. tile same for the description then here and finally for this title so now if I save this and then come back here to the browser as we can see everything is in English like it once where so we have all of these featured items but what if I change over to Spanish well if I do this as we can see the whole text is now in Spanish and the dynamic array is also in Spanish so as we can see this is very powerful we just Define the Json files and all we need to do is make sure that they are synchronized across all of your languages Now using cursor what I can do is select all of these so select this one then add to chat so this one add to chat then do the same for this one and I believe that's everything so with this two I can say add this last two to the n. Json file and so I now get this so here we have adapt description and embrace description so I can select these two copy them come here over to before last updated and then hit save and with this I can say t adapt description so we get that autoc complete right away and then Embrace description but we now need to add it to the Spanish translation so s. Jon and for this I believe we should be able to use GPT 3.5 instead and it's going to be much faster so translate and. adjacent to Spanish keep the properties or the keys in English the values are the ones to be translated and with this it's still not working but I guess it's because cursor uses the current file automatically so I'll move over to this one and try again and let's see if this time it works so seems like it did so now I can say s. adjacent and replace everything hit save and if I come back here as we can see in Spanish everything is now successfully translated now what about the date we still have January 5 2024 and in Spanish that's not the way a v is represented so for that again the library uses the ICU standard so if I come here to this blog post we have a short guide on how to use this standard so they have number formatting you can see that for yourself but they Al have the date and time formatting so if I move to this one as we can see the Syntax for date formatting is variable then comma then we specify the type so we're selling that the variable is a date and then we can pass in the format and this format if I come here we can say short medium long full and there are also these default formats and then they have the way to do this which is checking date comma date and then medium so let's try this out let's see how this works so I'll come here to the n. adjacent and in last updated we're going to pass in a variable so this will be the date then the type will be the date or or Clarity let's name this now and then we can pass in the format so we can say medium and with this we can come back here to product section and then instead of doing all of this we can get rid of this span and instead pass in the information so we can pass in the values which are those that we declared here so now so we can say now will be the new date and if I save this and then come back here it is not getting displayed because I forgot about the Spanish one so I can come here and say or just copy and paste this here and with this now the date is formatted to Spanish so that's how easy it is and you can do this for a lot of other formats so again you have the plurals so this is very nice because you can specify the variable so the one that you're going to be passing in just like we did and then you can say plural comma and then you can say when it's one you can say one room and when it's anything else like an else so we one do that else and then number so this is the placeholder and then you pass in that one for plurals and then you can also pass in other variables and these variables again are defined here so you pass in or you declare the name and this name will correspond to the one that you pass in in this object so the key of each property must mop to each variable declared here so let's try the plural so I'll come here to n and at the top I'll just have a plural test and here what we can do is say count and then we say the type will be plural and then we can say when it's equal to zero you can say zero tasks or whatever you want so this is an if so if equals zero so the count that you passed in then use zero tasks as the actual text otherwise you can say if it's equal to one then one Tusk and then other and then hashtag tasks so if I copy this I'll just paste it here in English because we're just going to be testing this and if I save this then here at the top let's see where we can add that the title let's also say t and then floral test and then we can passing the count so again this maps to the key so we can say two if I save this come back here we get two tasks if I change this to one it should say one task singular and if I say zero save this zero tasks so as you can see this format is really nice so now what if you want to have this select so English you click on it you can change over to German and vice versa how can you add that to your application well for that they have this example here which you can find in the official documentation so if you scroll down you'll find this example how can I Implement a local switcher and they tell you how to do it alongside with the example implementation so now this wraps up the video thank you for watching and if you want to see more content like this make sure to subscribe I'll see you in the next one
Info
Channel: Lucas Barake
Views: 13,971
Rating: undefined out of 5
Keywords:
Id: 7C3l4wIq8vQ
Channel Id: undefined
Length: 26min 20sec (1580 seconds)
Published: Sat Jan 06 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.