Skip to content

@apostrophecms/i18n

Alias: apos.i18n

Extends: @apostrophecms/module ℹ️

This module governs internationalization functionality and localization tools. Apostrophe projects will configure locales through @apostrophecms/i18n.

The module makes an instance of the i18next npm module available in Nunjucks templates via the __t() helper function. That function is also available on req objects as req.t() and in user interface Vue.js components as this.$t().

apos.i18n.i18next can be used to directly access the i18next npm module instance if necessary. It usually is not necessary. Use req.t if you need to localize in a route.

Options

PropertyTypeDescription
defaultLocaleStringThe locale that will be used by the UI and server rendering if no other is specified.
localesObjectThe set of locales to use in the application.
redirectToFirstLocaleBooleanIf enabled, and all locales matching the currently requested hostname have a prefix defined, it will redirect to the locale defined first. If the request does not match any explicit hostname assigned to locales, redirects to the first locale that does not have a configured hostname.
adminLocalesArrayThe locales that can be selected by the users for the admin UI
defaultAdminLocaleStringOptionally takes the locale key for the default Admin UI language. If not present, it will default to match the locale language. Overridden by the user preferences.

locales

The locale object should include one or more (usually two or more) locale configuration object. Each locale key is a short code, typically a two letter country code (e.g., ca), language code (fr), or one of each with a dash separating them (fr-CA). This local name is used to reference the locale throughout Apostrophe.

Each locale may have the following settings:

Locale settingTypeDescription
labelStringThe human-readable label for the locale.
hostnameStringA hostname (e.g., 'example.net') that will trigger the locale to be shown.
prefixStringA URL path prefix that will trigger the locale to be shown.
privateBooleanSetting this to true exposes this locale to logged-in users only.

Hostname and the path prefix are both factors in deciding what locale to display to visitors. There is prioritization that factors into identifying the correct one to use. The priority ranking for choosing the correct locale is:

  1. The locale has both hostname and prefix settings and the URL matches both settings.
  2. The URL matches the locale's configured hostname and the locale has no prefix
  3. The URL matches the locale's configured prefix and the locale has no hostname.
  4. The locale is the default locale (when no other locale matches).

Other notes:

  • Two or more locales may not be registered with the same hostname and the same path prefix. Apostrophe will throw an error in this case.
  • The default locale (either the defaultLocale setting or the first registered locale) does not need a hostname or path prefix setting.
  • If any locale has a hostname setting one of these must be true:
    1. The Apostrophe app must have a baseUrl set in the data/local.js or similiar server configuration file (a best practice in most cases anyway) or set through the APOS_BASE_URL environment variable, OR
    2. All locales must have a hostname setting (even if several are the same, using different prefix settings).
  • If the URL does not match any locale's set hostname or prefix (and all locales have one or both settings), Apostrophe will use the default locale.

Project configuration examples

javascript
module.exports = {
  options: {
    defaultLocale: 'fr',
    locales: {
      fr: {
        label: 'French'
      },
      'en-CA': {
        label: 'Canada (English)',
        prefix: '/ca/en'
      },
      'fr-CA': {
        label: 'Canada (French)',
        prefix: '/ca/fr'
      },
      'es-MX': {
        label: 'Mexico',
        hostname: 'example.mx'
      }
    }
  }
}

With redirectToFirstLocale option enabled.

In the following example, every locale has a prefix so if we request the base URL of the site without a locale prefix (/en or /us/en) in the URL, the first locale will be taken into account (en) and we will be redirected to /en.
Same thing if we request example.ca with no locale prefix, we will be redirected to /ca/en as it is the first locale configured with that hostname.

javascript
module.exports = {
  options: {
    defaultLocale: 'en',
    redirectToFirstLocale: true,
    locales: {
      en: {
        label: 'English',
        prefix: '/en'
      },
      'en-US': {
        label: 'English',
        prefix: '/us/en'
      },
      'en-CA': {
        label: 'Canada (English)',
        prefix: '/ca/en',
        hostname: 'example.ca'
      },
      'fr-CA': {
        label: 'Canada (French)',
        prefix: '/ca/fr',
        hostname: 'example.ca'
      }
    }
  }
}

adminLocales

The adminLocales takes an array of objects. Each of the objects should have a label that is presented to the user in both the user manager editor, and in the user preferences menu. This menu can be accessed through the dropdown at the right hand side of the admin-bar menu. The objects should also have a value property that takes the name of one of the configured locales or a JSON translation file being supplied to the project.

javascript
module.exports = {
  options: {
    defaultLocale: 'fr',
    locales: {
      fr: {
        label: 'French'
      },
      'en-CA': {
        label: 'Canada (English)',
        prefix: '/ca/en'
      },
      'fr-CA': {
        label: 'Canada (French)',
        prefix: '/ca/fr'
      },
      'es-MX': {
        label: 'Mexico',
        hostname: 'example.mx'
      }
    },
    adminLocales: [
      {
        label: 'Français',
        value: 'fr'
      },
      {
        label: 'English',
        value: 'en-CA'
      },
      {
        label: 'Espanõl',
        value: 'es-MX'
      }
    ]
  }
}

The following methods belong to this module and may be useful in project-level code. See the source code for all methods that belong to this module.

inferIdLocaleAndMode(req, _id)

Infer req.locale and req.mode from _id if they were not set already by explicit query parameters. Conversely, if the appropriate query parameters were set, rewrite _id accordingly. Returns _id, after rewriting if appropriate.

isValidLocale(locale)

Given a locale name, this will return a boolean value indicating whether it is a locale configured for the Apostrophe website.

matchLocale(req)

Return the best matching locale for the request based on the hostname and path prefix. If available the first locale matching both hostname and prefix is returned, otherwise the first matching locale that specifies only a hostname or only a prefix. If no matches are possible the default locale is returned.

Module Tasks

rename-locale

The rename-locale command moves all content from one locale name to another, using the --old and --new options. Note that the value of --new should match a locale name that is currently configured by the @apostrophecms/i18n module. By default, any duplicate keys for content existing in both locales will stop the process. However you can specify which content to keep in the event of a duplicate key error using the --keep=<localename> option where <localname>is either the old or new locale.

Usage: node app @apostrophecms/i18n:rename-locale --old=de-DE --new=de-de --keep=de-de