Manage Multilingual Content in Storyblok and Next.js
Storyblok is the first headless CMS that works for developers & marketers alike.
In this tutorial, we will see how to add and manage multiple languages on our website. We will be using Next.js built-in support for internationalization on the front-end. We will also take a look at how to manage multiple languages in Storyblok. Along with all this, we will also add a simple language switcher to our website.
You can read more about Next.js Internationalized Routing here.
There are four different approaches to implementing internationalization in Storyblok. You can use any one of them according to the requirements. In this tutorial, we will be using Field-Level translation. You can read more about all the approaches in detail here.
If you’re in a hurry, you can find the live demo for this tutorial here. Alternatively, you can explore or fork the code from the Next Ultimate Tutorial GitHub Repository.
Requirements
This is a part of the Ultimate Tutorial Guide for Next.js. You can find the previous part of the series here, which shows how to create custom components in Storyblok and Next.js. We recommend you to have completed that tutorial before starting this one.
We will be using the code from the previous tutorial as a starting point. You can find it here.
Adding a language in Storyblok
First, let's add a new language to our Storyblok space. Go to Settings {1} and click on Internationalization {2}. Here, you will find the configuration for field-level translation.
Although you can select any language you want, for the purpose of this tutorial we will use Spanish as the second language.
Let's select the Spanish language from the drop-down {3} and hit the Add button {4}. Once the Spanish language is added, save the changes by clicking on the Save button {5}.
If we go now to any of the stories, we will see a language dropdown on the action bar {1}.
We can switch the language from this dropdown. It won't work right now, because we haven't translated anything.
As this is field-level translation, we need to make the fields translatable. Let's edit the title
field of the article
block and mark it as translatable
{1}. Hit Save {2} after changing the field.
If we switch the language now, we will get a 404 from Next.js. This is because with getStaticPaths
inside our [...slug].js
and index.js
files, where we generate all the paths, we aren't generating the Spanish one. We will configure that in a while by adding the locale, and updating the Next.js config file.
If you take a look at the translatable field now, you can observe a change in the UI {1}. You will see that the field is non-editable and has the default language's content in it. But here we also have the option to translate it {2}.
If we enable it, we can edit the field and add the content in Spanish. There is also an arrow button {1} which we see after toggling the translate option. If we expand that, it allows us to see the default language's content, add the default language’s content to the field itself with just a click, and go to Google Translate.
Let's hit publish with the translated content and configure our Next.js app.
Configuring i18n in Next.js
Let's start with the next.config.js
file. We need to add the i18n config to this file. If the file is not present in your directory, you can create a new file in the root directory.
If you want to know more about the next.config.js
file, please take a look here.
Copy the following code inside your config file:
With this code, we are adding two locales in the project - English and Spanish (line 3). We also state our default locale which is English (line 4). Once you add this code, you will need to restart the server to see the changes as the changes are in the config file.
Now we will be able to access the locale info in our getStaticProps
and getStaticPaths
methods.
Let's change the getStaticPaths inside [...slug].js
to the following:
You can see that now we are generating the pages for all the locales we have. In this case, two of them - English (default) and Spanish.
Now if you refresh the page, you will see that we don't get a 404. Instead, we get the loaded page. But the loaded page is still using the default content. We need to update our getStaticProps
as well. In your [...slug].js
file, replace the getStaticProps
with the following:
If we now reload again, you will see that we get the new translated title.
You will need to do similar changes in the index.js
file. It will require more configuration to see the changes inside the visual editor for the home page as it has a real path set to it and will not change the path when the language is switched from the dropdown. It will work fine in the browser.
You can use the Advanced Paths app to configure the preview URL programmatically for the visual editor.
If we even try to switch the language from the dropdown, the content title also gets changed as we translated it. We can similarly translate more fields and content. The interesting thing is that this translation also works on more field types, for example, assets. We can even translate the image we have on the article page. We need to update the schema and mark it translatable similar to the way we did for the title.
Once done with the block schema update, we can now upload another image for the other language. This will allow us to use different images for different languages/regions.
That's it, this is how easily you can translate your content and manage multiple languages with Storyblok and Next.js. You can similarly translate all the blogs and any other content you want.
Let's also do a couple of more things like adding a language switcher in the navigation and translating the Blog homepage as it was getting the articles' data independently.
Adding a Language Switcher
As we will need to get the locale, and other related information inside the components like AllArticles.js
as well as inside the Navigation.js
, let's pass this information down through props. For this, we will need to first return this information from getStaticProps
. After that, we will pass it down in the Layout
component.
Replace the code inside [...slug].js
with the following:
You will need to make similar changes inside the index.js
file.
Now inside the Layout.js
file, we will pass this information to Navigation.js
with the props. The Layout.js
file should now look like this:
Now, once we get this locale information inside the Navigation.js
, we will use it to make the simple language switcher. Replace the code inside the Navigation.js
file with the following:
You will see that in this file, we loop through all the locales and use a method to change the locale whenever a locale is clicked.
After updating the navigation, the website should now have a working language switcher {1}
Right now, if we go to the Blog home by clicking on Blog
in the navigation, we will see even when the blogs are translated, the blog teasers are in English. This is because we are not fetching the locale-specific data inside the AllArticles.js component.
Translating the AllArticles Components
Let's start with passing the props through Page.js.
The new Page.js
file should look like this:
Now inside the AllArticles.js
, let's fetch the locale-specific data by adding the language parameter (line 9) to the API URL.
The updated code should look like this:
And now you will see that all of the articles on the Blog
homepage are translated.
Congratulations, now you can build a full-blown multilingual Next.js website with Storyblok!
Wrapping Up
In this tutorial, you saw how to add and manage multiple languages in our Next.js and Storyblok website using Storyblok's field-level translation approach with the built-in support for internationalization in Next.js. We also added a basic language switcher on the navigation bar of the website.
In the next part of this series, we will see how to Create a Preview Environment for Your Next.js Website. It will be published soon, along with more parts. In the meantime, you can already start managing content in different languages with Storyblok and Next.js.
Resource | Link |
---|---|
Storyblok Next.js Ultimate Tutorial | https://www.storyblok.com/tp/nextjs-headless-cms-ultimate-tutorial |
Stackblitz Demo | https://stackblitz.com/edit/manage-multilingual-content-in-storyblok-and-next-js |
Create and Render Blog Articles in Storyblok and Next.js | https://www.storyblok.com/tp/create-and-render-blog-articles-in-storyblok-and-next-js |
Storyblok Technologies Hub | https://www.storyblok.com/technologies |
Next.js Technology Hub | Storyblok Next.js Technology Hub |
Storyblok React SDK | storyblok/storyblok-react |