Cast your mind back to near the start of the previous chapter, where I defined the difference between internationalization and localization.
Many people probably use the terms interchangeably, even though there is a distinct difference. We covered the internationalization part in that chapter: now it’s the turn of localization!
With our layout updated to accept content in different languages, we can add that content. I’m using English and French – we’ve already added some content in both languages. Still, we will continue to refine and extend our support for these two languages over the following few pages. The only exception, of course, is that I’m using the well-known Lorem Ipsum service to provide content; it does mean that strictly speaking, we will have content in English, French, and Latin! Don’t worry, though, as the focus is very much on the first two. The Lorem Ipsum text is there as a matter of convenience.
Okay – let’s take up from where we left at the end of the previous chapter: we’ve sorted out the locales, set up formatted date support, updated the layout, and refined the header. The next task is to focus on updating labels over the site – we’ll start with adding French label values ready for use on our site.
Localizing Blog Content
We’re making significant progress in internationalizing our site – so far, we’ve added support for locales, adjusted dates, localized the layout, and updated the header. So – what’s next?
This is where things will get interesting – we’ve already added support for English, but to make our site truly international, we need to add a second language. I’ve chosen to add French, but feel free to adapt to another language if you prefer – the process is the same.
Let’s start with adding French language support – we should begin with creating a collection to store French content to keep it separate from the existing English content.
- 1.
First, go ahead and stop the Eleventy server – this will make sure we trigger the changes correctly when restarting the server.
- 2.
Next, crack open the .eleventy.js file, then scroll down to this line:
- 3.
Leave a line blank after the method, then add in this code:
- 4.
Save and close the file.
- 5.
Next, open the site.js file in the _data folder, then add this code in, after the closing curly brace}, as shown:
- 6.
Next, fire up your file explorer and copy the posts and pages folders, and index.njk from the en folder to the fr folder.
- 7.
Save and close all files open, then switch to a Node.js command prompt and change the working folder to our new project folder.
- 8.
At the prompt, enter this command and press Enter – Eleventy will recompile the code.
- 9.
If all is well, we should see content appear on our site – we’ve already seen the English version, so let’s test what it looks like for the French equivalent. The site will automatically open to http://localhost:8080/, so add fr to the end of the URL and browse to the second post. You will see something akin to Figure 9-1, shown at the bottom of that post.
Yes – we now have French content appearing! Granted, we still have work to do to make sure all of the copy is in French, but we’ve done the critical part to get the language support into our site. This last demo highlighted a few key points we should explore in more detail, so let’s take a moment to review the changes made before moving on to the next task.
Breaking Apart the Code Changes
Cast your mind back to the previous exercise, but one, where we updated the layout to incorporate new placeholder labels for displaying captions in different languages. It was a beast of an activity and one which might have seemed a lot of work, for very little change!
However, it was necessary to complete the groundwork needed to allow Eleventy to display labels in different languages. This last bit is now possible, thanks to the changes we made in the previous exercise – we started with the by-now-familiar stopping of the Eleventy server before adding a new collection method in .eleventy.js, called posts_fr. We then switched to the site.js file in the _data folder before supplementing it with new labels in the French language.
As an aside, you will notice that I’ve gone on ahead and updated more of the post content using the same principles outlined in this chapter.
As the final step, we copied across the posts and pages folders from the en folder to the fr folder, along with index.njk; the localization already in place will automatically update the URLs for each post or page file. We then finished by recompiling the site before previewing our changes in a browser.
Okay – what’s next? Well, there is one crucial part we’ve not touched on in each post: tagging. You know, the entries we add to classify posts on a per-subject basis? We already have this in place, but only for existing (English language) posts – let’s update it to take care of sorting posts based on the new language structure of our site.
Updating Post Tagging
If you spend any time reading online blogs, you will no doubt come across post tags – you know the kind of thing: content that is tagged to help make it easier to find and which if you were to select, you will find other posts that could be of interest.
Eleventy is no different – we’ve already created tags for our content, but these are in English: not ideal if we want to localize our content into other languages! To fix this, we need to make changes to links, layouts, and the source collection – the latter contains French and English content, so we will need to split this into two separate collections for our site to work correctly. Let’s start with updating the English language version first.
Updating the English Version
We will update the English version for this first of two exercises to lay some of the groundwork for additional languages. It means we can use a search and replace to edit the files when localizing the tags for the French version of our site.
- 1.
The first step, as always, is to stop the Eleventy development server – this will make sure we apply the latest changes when we restart the server at the end of the exercise.
- 2.
Move tags-list.njk and tags.njk into the root of the en folder, then copy both files into the fr folder – you should end up with four files in total, two of each in both the en and fr folders.
- 3.
Next, crack open a copy of post.njk in your editor, and amend this block of code as highlighted:
- 4.
We also need to update both auxpostslist.njk and postslist.njk, which are in the same folder – open each file in turn, then amend the href link to add in the locale property:
- 5.
The next change is in .eleventy.js – when it comes to running the site, we will see the names of our post collections appear in the tags, which we won’t want to see. To fix that, we need to exclude them from the collections – add the two entries to the filterTagList function, as shown:
- 6.
We also need to update the links and labels in the tag block and “Tagged…” lists. To do this, first, crack open tags-list.njk, then update the contents of the <h1> tag and add in the /en locale, as shown:
- 7.
Swap out the post count line in the same file (just before the last closing </span>) to this:
- 8.
Next, open tags.njk in the en folder, and apply similar changes here too, as shown:
- 9.
We’re almost there – the last but one change to make is in site.js, where we need to add replacement placeholder labels to pick up the right languages in each site. Open site.js, and add these three extra labels to the bottom of the en block, as shown:
- 10.
Save and close all files open, then switch to a Node.js command prompt and change the working folder to our new project folder.
- 11.
At the prompt, enter this command, and press Enter – Eleventy will now recompile the code:
- 12.
If all is well, we should see our site appear in a browser – it will automatically open to https://localhost:8080/, so add en to the end of the URL, then try browsing around the posts. We shouldn’t see any visual changes as such, as we’re using the same text as before but sourcing them from the site.js file (Figure 9-2).
If you want to check that labels are being sourced from the site.js file, then try changing the text against one of the values – you will see that change automatically appears in the site.
Wow – another monster demo! I try and keep them as short as possible, but there are times when needs must…. If you managed to get to this point, then well done: we’ve done most of the hard work to update the tags.
The bad news, though, is that we still have to update the tags for the French version of the site. The upside is that we’ve already completed the groundwork, so altering the French tags will be a lot easier. Let’s dive in and look at the steps required to complete the changes.
Breaking Apart the Code
When researching for this book, I had hoped that updating the tagging would be a simple affair – unfortunately, that doesn’t seem to have been the case! Making changes was simple, but we had to change quite a few items for tagging to look and work somewhere near expected! But I digress.
Although it seems like a lot of changes, many of them follow the same principles we’ve already used earlier in this chapter. We started with the usual shutting down of the Eleventy server before adding placeholder values to postslist.njk, auxpostslist.njk, and post.njk, before moving on to adding new entries to the filterTagList function in .eleventy.js, to prevent unwanted tags from being included in the listings.
Next up, we added more changes to the tags-list.njk file – this time, we added a locale and swapped the posts count line for an alternative version. You will notice that we’ve used hard-coded locales here; in an ideal world, we would refactor the code to use the {{ locale }} placeholder so we can make the code more reusable. In this case, though, as the file needs to sit under the en folder (to fit in with the localized structure), hard-coding the value is something we can live with in this instance. At the same time, we also added similar changes to tags.njk.
We then moved on to adding new labels and values in site.js so that the placeholder labels are replaced with the correct text on compiling the site. As the final step, we recompiled the code before previewing the results in our browser.
Okay – we’ve completed the English version: it’s time now to add the French tags as our additional language! This next exercise won’t be as involved as the first, as we’ve already done the hard work to update the core areas of the site. Let’s dive in and look at what else we need to change so that we end up with tagging available in two languages, one for each version of the site.
Dealing with French Content
I know that the last demo was something of a lengthy exercise – don’t worry, it’s not quite so involved for this next one! We’ve already implemented the main changes for the English version, so the changes should not be so involved.
That said, there are still a few places where we have to change code, so let’s get stuck in and start making those changes as part of our next exercise.
We’ve talked about using French, but if you want to use a different language, please feel free to do so: the key is to have posts in a different language to the English ones, so we can verify our site is working OK.
- 1.
First, open some of the posts in the fr folder. Go ahead and change some of the tags or content to French: this is so we can verify that the site displays French language posts, not English ones. I would recommend making sure you have some posts with the same tags so that we don’t just get one post back when checking the Archives page.
- 2.
Recompile the site, then browse the website at http://localhost:8080/fr to ensure only French posts appear, not English ones.
- 3.
Next, go ahead and stop the Eleventy development server – this will make sure we apply the latest changes when we restart the server at the end of the exercise.
- 4.
The first step in updating the tag labels to display French content is to add labels and values into site.js (as we did for the English language site). For this, open site.js and add this to the bottom of the file before the closing brackets:
The next few steps all involve files in the /fr folder – make sure you don’t edit the ones you’ve just updated in the /en folder!
- 5.
We also need to update the links and labels in the tag block and “Tagged…” lists. To do this, first crack open tags-list.njk from the fr folder, then swap the contents of the <h1> tag and add in the /fr locale, as shown:
- 6.
Swap out the post count line in the same file (just before the last closing </span>) to this:
- 7.
Next, open tags.njk, and apply similar changes here too, as shown:
- 8.
Save and close all files open, then switch to a Node.js command prompt and change the working folder to our new project folder.
- 9.
At the prompt, enter this command, and press Enter – Eleventy will now recompile the code:
- 10.
Try visiting the French site at http://localhost:8080/fr – you should see a similar change there, with new labels in French for tagging (Figure 9-3).
We are almost there with localizing the tags, but there is one essential task still left to complete – you will no doubt have noticed that even though we have localized sites, all of the tags display on the Archives page! This is something we don’t want, so we will fix that shortly – for now, let’s pause for a moment to review the code changes before tackling that task.
Understanding the Changes
We began with updating some of the tags and content in posts to be sure that when browsing around the site, we see content from the French site, not from the English one. Once done, we then stopped the server so that any changes we make are correctly applied when restarting the server.
Next up, we added new labels and values to the site.js file before switching to tags-list.njk to add the placeholder labels and locale values to the template. We also made similar changes to tags.njk before recompiling the code and previewing the results in our browser.
If you take a closer look at the code, you will notice that we hard-coded the locale values in this instance. Ordinarily, I would have preferred to use something like the {{ locale }} value from earlier in the chapter so that we can reduce duplication in the site.
I’ve hard-coded values, for now, to keep things simple. In the spirit of iteration, I would recommend refactoring the code to use just one instance of the component. Removing duplication is always worthwhile, but only if it doesn’t adversely affect how we architect the site’s code!
Okay – let’s continue: we’ve worked on updating tags to show in both the French and English language versions of the site. However, we still see all posts appear on the Archives page when we should only show those relevant to the target market. Displaying all of the tags on the page may not be an issue for some, but I suspect it will be for most people, so let’s look at what’s required to fix this issue in more detail.
Separating Content into Localized Collections
When constructing a multilingual site, we have to think about the content displayed on screen – this needs to be localized for a specific market, right? We, of course, don’t want to see French on an English site and vice versa; the issue we talked about at the end of the last demo is one we need to fix.
Fortunately, it’s not a complicated fix to implement – we’ll focus on the tags Archive page as this is where the problem is most acute. We need to update tags-list.njk, plus add some methods to build localized tag collections – we’ll begin with tagging the relevant posts, ready to create that tag collection.
- 1.
First, stop the Eleventy development server – we will need to restart it once we have made the changes so they take effect.
There should be two spaces before the hyphen in this example; if you find the tag failing, then check the spacing!
- 2.
Save and close the four post files.
- 3.
Next, switch to .eleventy.js and look for this line:
- 4.
In that function, go ahead and update the exclusion list as highlighted:
- 5.
Scroll down a little to the eleventyConfig.addCollection("tagList"...) method, then leave a blank line and add this new method:
- 6.
Open auxpostslist.njk and look for this line:
- 7.
Comment it out for now by wrapping it in {# #} tags – it causes an issue during compilation.
- 8.
Next, switch to the tags-list.njk file from within the en folder, and replace the <div class="tag-list"> block with this code:
- 9.
Repeat steps 1 to 9, but this time replace any instance of _en with _fr.
- 10.
Save and close all files open, then switch to a Node.js command prompt and change the working folder to our new project folder.
- 11.
At the prompt, enter this command, and press Enter – Eleventy will now recompile the code:
If you find that the tags page doesn’t update – try deleting the _site folder, then rerun the command to regenerate the folder.
- 12.
Try visiting the English site at http://localhost:8080/en/tags – if all is well, you should see just four entries present (Figure 9-4).
- 13.
If we check the French version, we should see something akin to the extract shown in Figure 9-5.
It might indeed seem like it was a lengthy exercise, but it’s an important one: a site’s styling may look fantastic, but the effect will be spoiled if we’re serving rubbish content, particularly when it comes to tagging! This demo illustrates some important points around the use of Eleventy methods to create collections, so let’s take a moment to review what we covered in the last exercise.
Exploring the Changes Made
One of the features in Eleventy is its ability to filter content – the best way to do this is to tag each piece with a suitable word, then create a collection that looks for just those posts with the chosen tag.
We used the principle here to generate our tag collection or (if you like) database. We started with the by-now-familiar step of stopping the Eleventy server before adding a new tag into the four posts within the en folder, which we will use to create the new tag collection.
Next up, we updated the filterTagList function to exclude some new tags that will appear due to this change, but we don’t want to appear to the reader. We then copy the original tagList method and adapt it to create that new tag collection.
We then moved on to updating tags-list.njk – here, we replaced the existing tag-list div with a new version. Ironically, most of the new version is similar to the previous one, but the critical change is to use collections.tagList_en as our source collection. We then repeated the exercise to update the French version before compiling and previewing the results in a browser.
Excellent – we have a site that displays the correct tags for each market, not just on the individual pages but also in the main tag archive list. However, before we move to refactor the index page, there are a couple of important points I want to touch on.
Developing the code for this part was more complex than at first thought: there was a time when I thought it might not be possible to achieve the split! Fortunately, I had some help from contributors on the main Eleventy site at https://www.11ty.dev; they pointed me in the direction of the advanced API methods, particularly the getFilteredbyTags method.
I had to take a leap of faith and play with the code a little, trying all manner of different combinations, until I realized that I could iterate through the collection as a chained method once I had implemented getFilteredbyTags within my collection method. It pays to experiment with some of the features in Eleventy – while some of the examples don’t (yet) have extensive documentation, there are more things we can do with some of these functions than at first might appear!
If you would like to refer to the docs for getFilteredByTags, then please browse to the Eleventy site at https://www.11ty.dev/docs/collections/#getfilteredbytags(-tagname-secondtagname-[...]-).
Okay – enough chitchat: let’s move on! As mentioned just now, the next task is to update the main index page; we have a few changes to make, so let’s start with adding placeholder labels ready to display content in different languages on this page.
Updating the Index Page
We’ve covered most of the site but have left probably the most critical page until last – the main index page. This page requires more changes compared to some of the other pages, as we have more features in use.
For this next exercise, I will run through the steps first in English – we will need to apply the same changes to the index.njk file within the fr folder.
A quick tip – You should be able to search and replace across the files in the fr folder once you’ve copied them over from the en folder.
- 1.
First, stop the Eleventy server as before – this will make sure the changes we make are applied correctly to the site.
- 2.
Next, crack open the index.njk file under the en folder in your editor, then change this line as highlighted:
- 3.
Scroll down to the page count block – modify the code so it matches the following code:
- 4.
Next up, we need to update the date displayed on each post tile so it is displayed in the right locale – for this, look for this line of code in partials/auxpostslist.njk:
- 5.
Change it to this:
- 6.
We also need to amend the pagination block too, inside the en/index.njk file – let’s first amend the links for previous posts, which we need to do in two places:
- 7.
There are two more changes we need to make inside the en/index.njk file for the pagination link to newer posts – add in the locale values as shown:
- 8.
To finish off this file, amend the code to add in the site[locale] value, as indicated:
- 9.
Go ahead and repeat steps 1–8 for the index.njk file in the fr folder, but use _fr in place of _en when updating the code.
- 10.
Save and close any files open, then switch to a Node.js command prompt and change the working folder to our new project folder.
- 11.
At the prompt, enter this command and press Enter – Eleventy will now recompile the code:
- 12.
This time, browse to http://localhost:8080/en, and try hovering on the links on a post – you should see it show a localized URL for the post within the English site (Figure 9-6).
- 13.
Try performing the same task again, but this time navigate to http://localhost:8080/fr – if all is well, we should see the French version of the site appear, as shown in Figure 9-7.
The title is in English, as we have not yet edited the post; focus on the bottom left of the image!
Our site is starting to take shape now – we’ve started to add content for a new language, which we can reuse the same principle for other languages in the future. This demo has covered some valuable points for internationalizing content, so let’s review these changes in detail.
Understanding the Changes Made
We’ve almost reached the point of completing the site – we still have one more task to do, which is to implement a language switcher option on our site. It’s not a requirement for all sites, but valuable for those countries that speak one or more languages, such as Belgium and Switzerland. We’ll tackle that shortly, but for now, let’s review the changes we’ve made in the last exercise.
We started with the by-now-familiar stopping of the Eleventy server before updating the pagination front matter tag property in the index.njk file from the en folder. We then worked through similar changes in the same file, such as adding placeholder labels or replacing the existing global collections with the posts_en one (step 3). At the same time, we updated the date format used in the posts – we did this already within individual posts, but this time we’re updating the post tiles shown on the index page (which have the same text displayed).
Next up, we repeated the first eight steps, but this time in the French language version of the site – as we were careful with naming the original English version, this made it easier as we could do a search and replace on a duplicate copy of the code.
We then rounded out the demo by recompiling the code and previewing the results in a browser, both in the English and French versions of the site.
Phew – we are almost done internationalizing our site, but there is one last task to complete. We have created English and French versions of our site, but there may be instances where we might want to switch between the two – such as for a country where multiple languages are spoken. Leaving aside whether this impacts aspects such as SEO, we should at least add in something to allow us to select the other site. It’s a quick change to make, so let’s dive in and take a look.
Adding a Language Switcher
Adding a language switcher doesn’t require anything special for our site; indeed, you could do things like creating collections based on a click of the link, but that is overkill for such a small site!
In our case, all we need is two links, labels, and flag icons; we already have content localized in separate collections, so there is no need to rebuild each time. Let’s dive in and look at what we need to add to set up the switch option in more detail.
- 1.
First, go ahead and stop the Eleventy server as we’ve done before – this will make sure the changes we make are applied correctly to the site.
- 2.
Next, crack open header.njk in the en folder: go ahead and add the <div> block before the closing </header> tag:
- 3.
We also need to do something similar for the header.njk file in the fr folder too:
- 4.
Go ahead and add this to code to the foot of _header.scss, as indicated:
- 5.
At the same time, look for this line, which is nested in the header selector:
- 6.
Change the properties defined just below it to this:
- 7.
Save and close any files open, then switch to a Node.js command prompt and change the working folder to our new project folder.
- 8.
At the prompt, enter this command and press Enter – Eleventy will now recompile the code:
- 9.
If all is well, we should see a new language switcher appear to the right of the header, as shown in Figure 9-8.
- 10.
Try navigating to the French site at http://localhost:8080/fr – you will notice something similar here too (Figure 9-9), albeit with the labels switched to give more prominence to the French label.
At last – something simple: I will grant that the previous few demos have been pretty meaty ones!
For once, our latest demo doesn’t use anything specific to Eleventy; we’ve already built out the two sites, so there was no need to use anything more complex than a couple of links, images, and some Sass styling to create our two links. You will notice, though, that I’ve switched the order; this is to give more prominence to the link that relates to the current site, so it appears first in the list. It’s not essential; we could use the same order for both sites!
Summary
We started where we left off from Chapter 8, with localizing blog content – this was to swap out hard-coded text and replace it with placeholder labels that can source content from a data dictionary during compilation.
We then explored how to update tagging for posts – this turned out to be a little trickier than planned, as refactoring the pages to display labels was straightforward. The difficulty came in creating the localized collections for storing English and French content separately – we eventually got there, but only after a bit of trial and error!
To round out our journey through internationalizing Eleventy sites, we then updated the most critical page, the index page; it uses the same principles for adding label placeholders, so it was relatively easy to update. At the same time, we also added a simple language switcher; given we have already created separate sites for both English and French content, we only needed to add links to each site.
Phew – we’ve certainly covered a lot over the last two chapters! We are almost at the end of the project, but there is one more task to perform before releasing our code into the wild. It’s tidy-up time – yes, I know it’s not everyone’s favorite task, but it’s still important to make sure everything looks presentable! We can do quite a few things to help refine the site, so stay with me, and I will reveal all.
Note For the last two chapters, we will revert to using the original version of the site as at the end of Chapter 7. This will help simplify releasing content to production; we will touch on what we should do for deploying localized sites toward the end of the chapter.