Translation

How to use i18n features to translate content & label


Configure languages

Add one or more languages to your site and define which one is used by default simply by editing project.config.js file.

./project.config.js

module.exports = {
languages: {
// Default language to be redirected to when no locale is specified .e.g / > /fr
default: "fr",
// Enables languages. Drupal must have these enabled.
enabled: ["fr", "ar", "en"],
// Languages labels, mostly used by dropdowns.
labels: [
{ code: "en", label: "English" },
{ code: "fr", label: "Français" },
{ code: "ar", label: "العربية" },
],
},
}
  • default: string
    • The default language when no locale is provided. Example: /blog/slug-for-article will redirect to /fr/blog/slug-for-article.
  • enabled: array
    • The list of the available languages you wish to enable
    • They should be enabled first in Drupal.
    • labels: array of objects:
      • The list of the languages that should be available to the user to choose from.
      • They will be used in a dropdown which allows users to choose their prefered language.
      • code should one of the enabled languages
      • label what to display as a label in the dropdown

Create and translate Content

Translating Drupal content is automatically handled for you, all you need is create translations in Drupal. To test your configuration, add a few test pages to Drupal and view them.

Translate Next.js

To translate Next.js labels, we use rosetta and React Context which holds all translations. This give us a hook called useI18n to use for translating labels in our components

./components/user-info.jsx

import { useI18n } from "@vactorynext/core/hooks"
export const UserInfo = () => {
const { t } = useI18n()
return (
<a
href="#."
className="inline-block bg-white py-2 px-4 border border-transparent rounded-md text-base font-medium text-indigo-600 hover:bg-indigo-50"
>
{t("Nx:Sign in")}
</a>
)
}
Make sure you prefix your keys with `Nx:`.

Add your translations to Drupal

So you did use useI18n, but no matter what language you choose, Next.js will always display the Nx:Sign in text. You may ask yourself, yes i did setup the Nx:Sign in, but where the translation actualy happens ?

Actualy, we store these translations in Drupal at http://localhost:8080/_translations. Doing so allows us to translate Next.js directly from Drupal without having to restart Next.js web server.

Remember that Context we talked about in the previous section ? We download the content of _translations from Drupal and store in that Context. That Context will provide us everything we need to fix this. So enough talking and head over to Drupal at /admin/config/regional/translate

  1. Click on Import Frontend
  2. Type in Nx:Sign in
  3. Hit Save

Know you can translate Nx:Sign in as you would normaly do in Drupal

Make sure to watch this video.

Debug translations

Language Switcher Configuration

To display only languages with existing translations:

  1. Go to admin/config/system/decoupled-switch-lang-settings in Drupal.
  2. Check the option Show only languages with translations for the current page.
  3. Save Configuration.

Next, update the SwitchLocale function in your header component as follows:

./components/header/HeaderWidget.jsx

const SwitchLocale = () => {
const router = useRouter()
const locale = router.locale
const { path_18n } = useNode()
// Filter out the current locale from the available languages
const availableLanguages = languages.filter(
(language) => path_18n[language.code] && language.code !== locale
)
// Hide the locale switcher if no other languages are available
if (availableLanguages.length === 0) return null
return (
<Menu>
<Menu.Items>
<div>
{availableLanguages.map((language) => {
const url = path_18n[language.code]
// Skip rendering if , translation doesn't exist
if (!url) return null
<Menu.Item as="div">
<a href={url}>{language.label}</a>
</Menu.Item>
})}
</div>
</Menu.Items>
</Menu>
)
}

This will disable the language switcher on pages without translations and display only available languages on translatable pages.