This is a preview of the Storyblok Website with Draft Content

How to translate slugs with Nuxt.js and Storyblok

Storyblok is the first headless CMS that works for developers & marketers alike.

In this article I explain how to use a translated slug with nuxt. I also show you a really simple real life example with Storyblok .

Use cases

You can use Storyblok for basically everything! Use it for e-commerce, a personal website, blog, etc. As you may know, these days SEO is really important. Having a translated URL for your website will boost your SEO performance. Check out the google documentation , it encourages you to do that.

Let's create the project

If you already have a project with nuxt and nuxt-i18n skip to the next point. Or check out the code directly. (Live demo )

bash

        
      npx create-nuxt-app myproject
    

Make sure to select axios. From here you need to install nuxt-i18n .

bash

        
      npm install --save-dev nuxt-i18n
    

You need to create a file store/index.js to activate the store in your NuxtJS project and make Nuxt i18n work.

Static page with translated slugs

For the static pages, you can check the docs . You can configure it in the module configuration inside your nuxt.config.js or directly in components. Here is an example of how to use it in a component:

pages/contact.vue

        
      <template>
  <div>Contact me</div>
</template>

<script>
export default {
  nuxtI18n: {
    paths: {
      en: '/contact-me',
      fr: '/me-contacter',
    }
  }
}
</script>
    

Important: If the filename is different from the default lang use this example to navigate to it.

        
      <nuxt-link :to="localePath({ name: 'contact' })">
    

Let's use dynamic URLs with Storyblok.

For dynamic URLs I could have used Nuxt content. But as I have worked on a lot of eCommerce websites, I prefer doing it with Storyblok .

First, let's see how to use dynamic routes parameters with nuxt-i18n. You will need to use 'i18n/setRouteParams' actions from your Vuex store. Your file will look like pages/_articleId.vue .

pages/_articleId.vue

        
      <template>
  <div>
    <h1>{{ content.seo.title }}</h1>
    <div>
      {{ content.seo.description }}
    </div>
  </div>
</template>

<script>
import { translatedSlugs } from '~/helpers/translated_slug'

export default {
  name: 'PageArticle',
  async asyncData(ctx) {
    const locale = ctx.app.i18n.locale === 'en' ? '' : 'fr'
    const param = ctx.params.articleId

    try {
      const article = await ctx.app.$storyapi.get(
        `cdn/stories/${locale}/articles/${param}`,
        {
          version: process.env.STORYBLOK_VERSION || 'draft',
        }
      )
      const story = article.data.story
      await ctx.store.dispatch('i18n/setRouteParams', translatedSlugs(story))

      return story
    } catch (e) {
	   // your error handler
    }
  },
  data: () => ({
    content: { seo: {} },
  }),
}
</script>
    

And that's it! Now your visitors can enjoy URLs in their native language.

Thanks for reading this article and if you want to support me you can buymeacoffee .

Thank's to Josh Deltener for reviewing the article.