Manage Multilingual Content in Storyblok and Nuxt
Storyblok is the first headless CMS that works for developers & marketers alike.
Let’s see how to add and manage multiple languages on our website. For internationalization on the front end, we will use the @nuxtjs/i18n
module and develop a simple language switcher in our header. For the backend, we will see how to manage multiple languages in our Storyblok space and how to get the translations from our codebase.
You can read more about the @nuxtjs/i18n@next
module here.
Before starting with the practical part, it is important to know that Storyblok has three different approaches to implementing internationalization. In this tutorial, we will be using Field-Level translation. Depending on your requirements it will make sense to use one instead of the other. You can read all about the different approaches in our Internationalization guide.
If you’re in a hurry, have a look at our live demo in Stackblitz! Alternatively, you can explore or fork the code from the Nuxt Ultimate Tutorial GitHub Repository.
Requirements
This tutorial is part 6 of the Ultimate Tutorial Series for Nuxt. We recommend that you follow the previous tutorials before starting this one.
We will use 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 now go to the Content section and open any Story, we will see a language drop-down in the action bar {1}.
Switching the language from the drop-down won't work because we haven't translated anything yet.
Since we’re using the field-level translation approach, we need to make the fields translatable in our component schema in order to allow the translation of our content. Let's edit the title
field of the article
Content Type and mark it as (Translatable) {1}. Hit the Save & Back to Fields button after changing the field {2}.
If we change the language now, we will get a 500 error in Nuxt. This is because when we make the API calls we are not specifying the language yet. We will configure it in a while by adding the @nuxtjs/i18n
module and the Spanish (es) locale in the nuxt.config.js
file.
Looking now at the translatable field, you will notice a change in the UI. You will see that the field is non-editable and has the default language's content in it {1}. If we want to translate it, we must click on the Translate checkbox {2}.
By activating it, we will be able to edit the field and add the content in Spanish. But not only that. As we can see in the screenshot below, when we activate the translate option, an arrow button {1} appears. If we expand it, we will see the default language content {2}, a button to add the default language content in the new language {3}, and the option to go to Google translate {4}.
Let's hit the Publish button with the translated content and configure our Nuxt 3 app.
Configuring @nuxtjs/i18n module in the Nuxt project
Let's start with the installation of version 8 of the package @nuxtjs/i18n
, which is compatible with Nuxt 3, by running the command below:
The next step is to include the module and the i18n configuration in the nuxt.config.js
file at the root of our project:
With this code, we are adding two locales in the project - English and Spanish (line 9), and setting our default locale as English (line 10). Once you add this code to your project, you will need to restart the server to see the changes.
The 'prefix_expept_default' strategy causes all your routes to have a locale prefix added except the default language. See the official documentation of @nuxtjs/i18n@next module to learn more about the available options.
Now we will be able to access the locale information in the whole project. However, to see the translations coming from Storyblok we will need to change a couple of components first, starting with our main slug view.
Open pages/[...slug].vue
and update its script setup
specifying the locale and creating a custom useAsyncData
call using the Storyblok composable useAsyncStoryblok
:
As you can see in the code above, we are using the locale (line 4) selected by the user, or coming from the slug, to make the API request (line 12). Now, if you refresh the page, you will see that we don't get a 500 anymore. Instead, we get the translated version page.
For the home page, as it has a real path set to it, it won't change the path when the language is switched from the dropdown. It will only work fine in the browser. You can use the Advanced paths app to configure the preview url programmatically for the visual editor.
When changing the language from the dropdown in Storyblok, or try to modify the title, we will see that the content of the translations is also modified in real-time. Moreover, text-type fields are not the only ones that can be translated, the translation also works in several types of fields, even in the assets. For example, we can translate the image we have on the article page, but for that, we have to update the schema of the Article
Content Type and mark it as translatable in a similar way as we did with 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.
Now that we can see our pages translated, we must refactor our internal links, NuxtLink
, using the useLocalePath()
method the i18n module provides us. This way, the links of our page will have the corresponding locale automatically added to each URL.
Let’s start with the shared component ArticleCard.vue
:
Followed by the Header.vue
:
That's it; this is how easily you can translate your content and manage multiple languages with Storyblok and Nuxt 3. Similarly, you can translate all the blogs and any other content you want. Let's also do a couple more things, such as adding a language switcher in the navigation and translating the Blog homepage as it is currently configured to receive the articles' data in the default language.
Adding a Language Switcher
We will use a couple of variables and methods from the i18n module to make the language switcher, making its creation super simple. Just replace the Header.vue
with the code below:
First, we get all locales available in our project. Next, we loop through all the locales using v-for
and we use the switchLocalePath()
method to switch to the selected locale. After updating the main navigation, the website should now have a working language switcher {1}:
There’s only one thing left. Right now, if we go to the Blog homepage by clicking Blog
from the navigation when Spanish is selected, the blog teasers are in English. This is because we are not fetching the locale specific data inside the AllArticles.vue
component.
Translating AllArticles Component
Now, inside the storyblok/AllArticles.vue
component, let's fetch the specific data according to the locale by adding the language parameter to the API url. The updated code should look like this:
After implementing these changes you will see that all articles within the Blog story are translated.
Wrapping Up
Congratulations, you are now able to build a full-blown multilingual Nuxt 3 website using Storyblok and i18n! In this tutorial, you saw how to add and manage multiple languages in your Nuxt 3 and Storyblok website by the Storyblok's Field-Level translation approach using the internationalization module @nuxtjs/i18n
. We also added a basic language switcher on the navigation bar of the website, so that your project is ready to go to the market and serves as a base for future projects.
The next part, exploring how to Create a preview environment for your Nuxt application, is already available.
Resource | Link |
---|---|
Storyblok Nuxt 3 Ultimate Tutorial | https://www.storyblok.com/tp/storyblok-nuxt-ultimate-tutorial |
Storyblok Nuxt 3 Module | https://github.com/storyblok/storyblok-nuxt |
Storyblok Nuxt Technology Hub | https://www.storyblok.com/tc/nuxtjs |
Storyblok APIs | https://www.storyblok.com/docs/api |
Nuxt 3 | https://v3.nuxtjs.org/ |
Nuxt i18n | https://v8.i18n.nuxtjs.org/ |