Multi-language applications
(via Vocab)
If your application supports multiple languages you can designate those languages with the languages configuration.
Languages can be either a string, e.g. en, or an object that designates a parent language.
E.g. {name: "en-AU", extends: "en"}
NOTE
sku assumes that the development language is en. sku uses this as the base language for all development, including your initial translations.
Getting started
To enable multi-language builds, follow three steps:
- Install
@vocab/reactas a dependency. Your code uses this package to load the correct language translations dynamically inside React components. - Add the list of supported
languagesto your sku configuration
export default {
languages: ['en', 'fr'],
} satisfies SkuConfig;- Create your first .vocab folder. See Usage.
Usage
To create your first translation, create a folder ending in .vocab. Add a file in it called translations.json. This folder can be anywhere in your source code.
E.g. ./App.vocab/translations.json
In the file, add translations in the form of translationKey: { message: "The english translation" }.
TIP
You can use any key that you like. We recommend a copy, or a simplified version, of the English translation.
Once created, when you run yarn start or yarn build, sku creates the files that let you import the translations into your code.
E.g. ./App.vocab/index.ts
TIP
You can add translations files anywhere in your source code. We recommend co-locating components with their translations. When you want to re-use a translation in multiple places you can move the translations.json as needed.
Now with the appropriate files created you can start importing your translations.
import translations from './App.vocab';
import { useTranslations } from '@vocab/react';
export function MyComponent() {
const { t } = useTranslations(translations);
return <div>{t('my key')}</div>;
}See the Vocab documentation for the full syntax.
Complex messages
Sometimes a translation needs a dynamic value, or custom formatting, in the middle of the message.
Use the ICU Message syntax.
Site specific languages
If one of your sites only supports a subset of languages you can specify them in the site config.
Example: Setting an english only site.
export default {
languages: ['en', 'fr'],
sites: [
{
name: 'multi-language-site',
host: 'my.site',
routes: ['/$language/'],
},
{
name: 'english-only-site',
host: 'en.my.site',
routes: ['/'],
languages: ['en'],
},
],
} satisfies SkuConfig;NOTE
Any language specified by a site must be included in the top level languages field.
Route specific languages
Like a site, a route can also limit the languages it uses.
Example: Language specific URL
export default {
languages: ['en', 'fr'],
routes: [
{ route: '/hello', languages: ['en'] },
{ route: '/bonjour', languages: ['fr'] },
],
} satisfies SkuConfig;NOTE
Any language specified by a route must be included in the top level languages field.
Hierarchy
In general, you will want to create a full set of translations for every supported language. Some languages may only need small changes to a base language.
For example, you may only need to translate a few strings with different spelling, such as color to colour between 'en-US' and 'en-AU'.
In this case you can have one language extend another. sku then copies any missing translations from the base language to the more specific language.
TIP
Avoid using a language extension where you do not want to risk sending the wrong translation to production. sku has no way to validate whether you missed a translation on purpose or by mistake.
Custom locale
When formatting ICU messages, Vocab formats values such as dates and numbers according to the current language. In general, the language should match the locale that you want to use to format messages. Where it does not, you can set the locale separately in <VocabProvider>.
E.g. Using en-AU as the locale but only using one central en language.
<VocabProvider language="en" locale="en-AU">
<App />
</VocabProvider>Translation Platforms
sku supports specific features from 3rd-party translation platforms. Currently the only translations platform supported by sku is Phrase.
Phrase-specific Features
Translation Syncing
You can use sku to synchronize your translations to and from Phrase.
Phrase syncing requires two environment variables: PHRASE_PROJECT_ID and PHRASE_API_TOKEN.
PHRASE_PROJECT_ID must be set to your project's ID. You can find it in your project's settings under the "API" section.
PHRASE_API_TOKEN must be set to an access token. You can create one on the profile settings page.
Push or pull translations with Phrase:
$ sku translations push$ sku translations pullAutomatic Translation
Phrase can automatically translate content using machine-learning.
You can configure this in your Phrase project. Phrase may not automatically translate keys uploaded by the API.
To instruct Phrase to translate keys use --auto-translate.
$ sku translations push --auto-translateDelete Unused Keys
When uploading translations, Phrase identifies keys that exist in the Phrase project, but were not referenced in the upload. These keys can be deleted from Phrase by providing the --delete-unused-keys flag to sku translations push. E.g.
$ sku translations push --delete-unused-keysTags
The Phrase platform lets you attach tags to translation keys.
sku pushes any tags present in your translations.json file to Phrase when you use the sku translations push command.
See the Vocab documentation for how to add tags to your translations.
Pseudo-localization
When an app configures languages, sku generates the en-PSEUDO language automatically.
en-PSEUDO is a generated language created by pseudo-localizing existing en translation messages in your app.
See the Vocab docs for the pseudo-localization process. That page also covers possible use cases for this language.
en-PSEUDO can be consumed just like any other language in your app:
<VocabProvider language="en-PSEUDO">
<App />
</VocabProvider>