SEO
Introduction
@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:
- langattribute for the- <html>tag
- hreflangalternate link generation
- OpenGraph locale tag generation
- canonical link generation
Read more about those features below
Requirements
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.)
Setup
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:
- the head()option within the Nuxt configuration file (nuxt.config.ts)
- the head()component option in your page components or layout files
To 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 })
  }
}
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
      ]
    }
  }
}
Feature details
- langattribute for the- <html>tag
 Sets the correct- langattribute, equivalent to the current locale's- isovalue, in the- <html>tag.
- hreflangalternate link
 Generates- <link rel="alternate" hreflang="x">tags for every configured locale. The locales'- isovalue are used as- hreflangvalues.
 Since version v6.6.0, a "catchall" locale hreflang link is provided for each locale group (e.g.- en-*) as well. By default, it is the first locale provided, but another locale can be selected by setting- isCatchallLocaleto- trueon that specific locale object in your @nuxtjs/i18n configuration. More on hreflang
 An example without selected "catchall" locale:nuxt.config.ts- i18n: { locales: [ { code: 'en', iso: 'en-US' // Will be used as "catchall" locale by default }, { code: 'gb', iso: 'en-GB' } ] }
 Here is how you'd use- isCatchallLocaleto selected another locale:nuxt.config.ts- i18n: { locales: [ { code: 'en', iso: 'en-US' }, { code: 'gb', iso: 'en-GB', isCatchallLocale: true // This one will be used as catchall locale } ] }
 In case you already have an- enlocale- isoset, it'll be used as the "catchall" without doing anythingnuxt.config.ts- i18n: { locales: [ { code: 'gb', iso: 'en-GB' }, { code: 'en', iso: 'en' // will be used as "catchall" locale } ] }
- OpenGraph Locale tag generation
 Generatesog:localeandog:locale:alternatemeta tags as defined in the Open Graph protocol.
- Canonical link
 Generatesrel="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:- When using the prefix_and_defaultstrategy 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.
- When the page contains query parameters, the canonical link will not include the query params by default. This is typically the right thing to do as various query params can be inserted by trackers and should not be part of the canonical link. This can be overridden by using the canonicalQueriesoption. For example:export default { head() { return this.$nuxtI18nHead({ addSeoAttributes: { canonicalQueries: ['foo'] } }) }
 
 More on canonical
- When using the