@nuxtjs/i18n provides the $nuxtI18nHead
function which you can use to generate SEO metadata to optimize locale-related aspects of the app for the search engines.
Here are the specific optimizations and features that it enables:
lang
attribute for the <html>
taghreflang
alternate link generationRead more about those features below
To leverage the SEO benefits, you must configure the locales
option as an array of objects, where each object has an iso
option set to the locale language tags:
i18n: {
locales: [
{
code: 'en',
iso: 'en-US'
},
{
code: 'es',
iso: 'es-ES'
},
{
code: 'fr',
iso: 'fr-FR'
}
]
}
You must also set the baseUrl
option to your production domain in order to make alternate URLs fully-qualified:
i18n: {
baseUrl: 'https://my-nuxt-app.com'
}
(Note that baseUrl
can also be set to a function. Check baseUrl
documentation.)
The $nuxtI18nHead
function returns metadata that is handled by the Vue Meta plugin that is integrated within Nuxt. That metadata can be specified in various places within Nuxt:
head()
option within the Nuxt configuration file (nuxt.config.ts
)head()
component option in your page components or layout filesTo enable SEO metadata, declare a head
function in one of the places specified above and make it return the result of a $nuxtI18nHead
function call.
To avoid duplicating the code, it's recommended to set that option globally in your nuxt.config.ts
file and potentially override some values per-layout or per-page component, if necessary.
export default {
// ...other Nuxt options...
head() {
return this.$nuxtI18nHead({ addSeoAttributes: true })
}
}
Unfortunately such head()
definition can crash during static generation (nuxt generate
) due to Nuxt executing that function in a non-Vue Component context during generation of the fallback
file. If this issue affects you then null-check this.$nuxtI18nHead
before calling it.
Check out the options you can pass to the $nuxtI18nHead
in the API documentation.
That's it!
If you also want to add your own metadata, you have to merge your data with the object returned by $nuxtI18nHead
. Either as in the example below or using some library like deepmerge
to perform a deep merge of two objects.
export default {
// ...other Nuxt options...
head() {
const i18nHead = this.$nuxtI18nHead({ addSeoAttributes: true })
return {
htmlAttrs: {
myAttribute: 'My Value',
...i18nHead.htmlAttrs
},
meta: [
{
hid: 'description',
name: 'description',
content: 'My Custom Description'
},
...i18nHead.meta
],
link: [
{
hid: 'apple-touch-icon',
rel: 'apple-touch-icon',
sizes: '180x180',
href: '/apple-touch-icon.png'
},
...i18nHead.link
]
}
}
}
lang
attribute for the <html>
taglang
attribute, equivalent to the current locale's iso
value, in the <html>
tag.hreflang
alternate link<link rel="alternate" hreflang="x">
tags for every configured locale. The locales' iso
value are used as hreflang
values.en-*
) as well. By default, it is the first locale provided, but another locale can be selected by setting isCatchallLocale
to true
on that specific locale object in your @nuxtjs/i18n configuration. More on hreflangi18n: {
locales: [
{
code: 'en',
iso: 'en-US' // Will be used as "catchall" locale by default
},
{
code: 'gb',
iso: 'en-GB'
}
]
}
isCatchallLocale
to selected another locale:i18n: {
locales: [
{
code: 'en',
iso: 'en-US'
},
{
code: 'gb',
iso: 'en-GB',
isCatchallLocale: true // This one will be used as catchall locale
}
]
}
en
locale iso
set, it'll be used as the "catchall" without doing anythingi18n: {
locales: [
{
code: 'gb',
iso: 'en-GB'
},
{
code: 'en',
iso: 'en' // will be used as "catchall" locale
}
]
}
og:locale
and og:locale:alternate
meta tags as defined in the Open Graph protocol.rel="canonical"
link on all pages to specify the "main" version of the page that should be indexed by search engines. This is beneficial in various situations:prefix_and_default
strategy there are technically two sets of pages generated for the default locale -- one prefixed and one unprefixed. The canonical link will be set to the unprefixed version of the page to avoid duplicate indexation.canonicalQueries
option. For example:export default {
head() {
return this.$nuxtI18nHead({
addSeoAttributes: {
canonicalQueries: ['foo']
}
})
}