Multilingual TemplatingBeta

This article helps collect all the resources you need to take advantage of Prismic's multi-language and localization feature when building a Nuxt.js website.


Add languages to your repository

The first step is to go to your Dashboard, select your Prismic repository, and add all the languages you need in your repo's Settings. Prismic offers a robust library of language codes, but you can create a custom locale if the one you need isn't on the list.


Query by Language

By default, the API will return content in your master language. Here's how to dynamically query alternate languages; in each example, we pass the language code to the query option from the URL. Learn more about Querying content from the CMS.

You can query docs using the $prismic query helper or the SliceZone. Look at the following examples:

  • $prismic
  • SliceZone
Copy
<script>
export default {
  async asyncData({ $prismic, params, error }) {
    const document = await $prismic.api.getByUID('post', params.uid, { lang: params.lang })
    if (document) {
      return { document }
    } else {
      error({ statusCode: 404, message: 'Page not found' })
    }
  }
}
</script>
Copy
<template>
  <slice-zone
    type="post"
    :uid="$route.params.uid"
    :lang="$route.params.lang"
  />
</template>

<script>
import SliceZone from 'vue-slicezone'

export default {
  components: {
    SliceZone
  },
}
</script>

Create dynamic page routes

You can create localized routes for your dynamic pages and the homepage of your site. In the following example, we have two languages, English as the master locale and French as the second. Let’s see the routes we want to build:

For the homepage:

  • English: /
  • French: /fr-fr

For the dynamic pages, we want to use the lang code and the document's UID:

  • English: /about-us
  • French: /fr-fr/a-propos-de-nous

Let’s go to the first step to create these routes.

1. Create the document structure

If you’re familiar with how Dynamic pages in Nuxt work, you know that any file in the pages directory that is prefixed with an underscore _ is defined so that dynamic values are added to the routes and since the routes will mimic the order of our directories, we'll build them in that same way.

Now, let's see the example. Inside /pages, the _lang folder will prepend the lang code to each route of the site. Inside that same folder, _uid.vue will create dynamic routes using the UID of our documents and index.vue the. homepage route.

Then, we'll import these two files in the other _uid.vue and index.vue at the same level as the _lang folder to have a version of the routes without the language code, in this case for English.

Copy
// import for one page to another
<script>
import _uid from '~/pages/_lang/_uid'
export default _uid
</script>

2. Create your links

Once your routes are created you will need to create internal links that lead to the right routes either using a Link Resolver or the Route resolver. In these examples, we configure the routes so that the lang code is omitted from the route for the master language. (remember that the Custom types and master language 'en-us' are example values. Modify them to match yours):

  • Link Resolver
  • Route Resolver
Copy
export default function (doc) {
  if (doc.type === 'homepage') {
    return `/${doc.lang}`
  }

  if (doc.type === 'page') {
    return `/${doc.lang}/${doc.uid}`
  }

  return '/not-found'
}
Copy
prismic: {
  endpoint: "https://my-repo-name.cdn.prismic.io/api/v2",
  apiOptions: {
    routes: [
      {
        type: 'homepage',
        path: '/:lang?,
      },
      {
        type: 'page',
        path: '/:lang?/:uid',
      }
    ]
  }
},

Add this new file in the directory structure ~/app/prismic/link-resolver.js.


Create a language switcher

Now you'll need to create a navigation button to switch between languages. We'll use the NuxtLink component and the Link Resolver to navigate between pages.

Pass the alternate languages as props

First, in the page query, get the alternate_languages value from the response and pass it as props to the lang switcher component (we'll create it in the next step). In this example, we're dynamically querying documents of the type 'Page' in the _uid.vue file:

Copy
<template>
  <div>
    <lang-switcher :altLangs="altLangs"/>
    <!-- Slices block component -->
    <slices-block :slices="slices" />
  </div>
</template>

<script>
import LangSwitcher from "~/components/LangSwitcher.vue";

export default {
  name: "page",
  components: {
    LangSwitcher,
  },
  async asyncData({ $prismic, params, error }) {
    try {
      // Languages from API response
      let languages = $prismic.api.data.languages

      // Setting Master language as default language option
      let lang = { lang: languages[0].id }

      // Query to get document content
      const result = await $prismic.api.getByUID('page', params.uid, lang)

      return {
        // Document content
        slices: result.data.body,

        // Lang switcher
        altLangs: result.alternate_languages
      };
    } catch (e) {
      // Returns error page
      error({ statusCode: 404, message: "Page not found" });
    }
  }
};
</script>

Create a Lang switcher component

In the /components folder create a LangSwitcher.vue component and use the alternate languages passed to it to create a switch. This can be anything from a toggle, a select, or a button. For our example, we'll use a simple link which uses nuxt-link that, with the help of the linkResolver, will render the alternative language available.

Copy
<template>
  <section class="lang-switcher">
    <nuxt-link :to="$prismic.linkResolver(altLang)">
      <span>{{ altLang.lang }}</span>
    </nuxt-link>
  </section>
</template>

<script>
export default {
  props: ["altLangs"],
  name: "lang-switcher",
};
</script>

Extra:
To add a flag as your switcher button you can use the 'flag icon' CSS library. Just include it in your nuxt.config.js and add it to your switcher.


Related articles:

Read the full documentation on how to create simple routes with the help of the Link Resolver: