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.
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.
Once you have your languages configured, you can start creating documents and translations. We have several articles to help you learn how to do this.
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
<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>
<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>
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.
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.

// import for one page to another
<script>
import _uid from '~/pages/_lang/_uid'
export default _uid
</script>
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
export default function (doc) {
if (doc.type === 'homepage') {
return `/${doc.lang}`
}
if (doc.type === 'page') {
return `/${doc.lang}/${doc.uid}`
}
return '/not-found'
}
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.
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.
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:
<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>
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.
<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.