Skip to content

Latest commit

 

History

History
239 lines (158 loc) · 9.67 KB

i18n.md

File metadata and controls

239 lines (158 loc) · 9.67 KB

Internationalization (i18n)

Stelace Instant template includes English (default) and French translations out of the box, and can be translated to many more languages.

Structure

During build all your translations are transformed and merged from:

  • local entries defined in .yaml translation files committed to your git repository
  • your entries saved with Stelace Content API enabling live content updates.

Merging happens on build time, providing best performance for end-user.

Vue app still offers up-to-date contents since it requests Content API during boot, in a non-blocking way.

Note: You can change your default locale in .env files. All translations for this locale will be included in app bundle.

Local content entries

Translations .yaml files are located in src/i18n/source folder.

For easier maintenance translations are nested under entry names and a single translation key maps to all languages:

entry:
  field:
     en: English
     fr: French
  nested:
    field:
      en: Plain {SERVICE_NAME} text
      en_gb: You can translate to locales rather than languages too
      fr: Texte en clair {SERVICE_NAME}
      es: Texto sin formato
      context: Additional context can help translators
      # You may also come across translations keys suffixed with '__EDITOR_LABEL'.
      # They allow to provide content managers with additional context in several languages
      # when using Stelace Dashboard.

A .json file is generated for any language having at least one translation.

{
  // fr.json
  "entry": { // equivalent to Stelace Content API Entry object
    "field": "French",
    "nested.field": "Texte en clair {SERVICE_NAME}"
  },
  // …

src/i18n/theme yaml files can be used to keep your own translations in their own files in your fork and ease updates from main repository.

src/i18n/email translations are used in emails sent by your Stelace Email API calls or Workflows. Please refer to Email template API reference.

Content API entries

Stelace Content API enables your content team / translators to edit contents live.

Our headless CMS implementation offers both fresh content and best performance for your visitors, unlike other solutions available.

We merge Content Entry API contents with local translations during each build and fetch new contents in a non-blocking way on each pageload 🚀.

Building JSON files

After changes on the .yaml files, run yarn translate to trigger a refresh of Vue app and render new contents, based on new json translation files automatically built.

Note: yarn translate:prod will use your .env.production publishable API key to retrieve Content API entries.

Uploading website translations

After changing default translations in codebase and building the app, you can deploy your main language/locale just before pushing your code for continuous deployment:

yarn deploy:translations
# or
yarn deploy:translations:prod
# STELACE_SECRET_API_KEY will be loaded from `.env.development` or `.env.production`
# depending on which command you use.
# Your are free to set any live or test secret key as env variable during your deployment process.

Note: your translations are automatically uploaded once by default when running yarn dev, using STELACE_SECRET_API_KEY in env.development file.

You have to upload these yourself in production, generally using your live STELACE_SECRET_API_KEY in .env.production file and running yarn deploy:translations:prod after building the app.

This allows any authorized member of your team to browse all default contents used on your website from Stelace dashboard.

Values edited in dashboard by your team members will be saved to entry fields while default values in codebase have been set in metadata._instant namespace by this script.

This way default contents uploaded from local .yaml files (compiled to json) are updated in Content API and show up in dashboard editor after each deployment.

On the other hand your content team can edit contents live without having to tamper with default translations in your git repository, enabling easy reset to default contents right from dashboard.

Upload all or specific locales

To deploy all locales instead of your main locale only (VUE_APP_DEFAULT_LANGUAGE env variable):

yarn deploy:translations -a
# or
yarn deploy:translations --all

You can also deploy specific locales:

yarn deploy:translations -l en,fr
# or
yarn deploy:translations --locales en,fr
Comparing local and API translations

You can see all changes made with API/dashboard on top of your default yaml translations by simply adding --verbose option when building translation files:

yarn translate -v

Adding translations

Before adding new translations, you may want to ensure no existing one is appropriate with a search in src/i18n/source and src/i18n/theme folders in your editor.

A slight change in either your new content or in existing translations could spare one extra entry to translate.

Markdown support

Enjoy rich-text content in your translations with markdown syntax.

All commonMark syntax is supported, along with Github flavored markdown tables and strikethrough.

You just have to add [markdown] suffix to any translation key to enable automatic rendering to HTML during build.

not_markdown:
  en: Plain {SERVICE_NAME} text
  fr: Texte {SERVICE_NAME}
terms_optin[markdown]:
  en: I read and agree to the [Terms of Service]({terms_path}) applicable on {SERVICE_NAME}.
  fr: J’ai lu et accepte les [Conditions Générales d’Utilisation]({terms_path}) de {SERVICE_NAME}.

will be rendered as the following in src/i18n/build/en.json:

{
  "not_markdown": "Plain {SERVICE_NAME} text",
  "terms_optin": {
    "editable": "I read and agree to the [Terms of Service]({terms_path}) applicable on {SERVICE_NAME}.",
    "transform": "markdown",
    "transformed": "<p>I read and agree to the <a href=\"%7Bterms_path%7D\">Terms of Service</a> applicable on {SERVICE_NAME}.</p>\n"
  }
}

As a convention, having Content Entry object value (such as terms_optin object above) with editable and transformed keys mean transformed content needs to be rendered as HTML in Vue app.

This way you can also edit markdown contents using Content API outside this project as long as you keep transformed value in sync with editable. Note that it is automatically done when editing from Stelace Dashboard.

Multi-line with YAML

You can use >, |, >-, |- YAML block styles to write multi-line strings which is often needed in Markdown or for long text.

You generally want to use >- to ignore new lines and prevent parser from adding a line break at the end.

Here are some very useful examples on StackOverflow.

ICU Syntax

You may have noticed in markdown example above that we use ICU MessageFormat syntax ({SERVICE_NAME}).

You can learn and experiment on this nice website.

ICU enables advanced i18n with plurals, gender and conditionals using standard syntax.

We are using and contributing to vue-intl rather than vue-i18n for built-in ICU Message Format support.

Multi-language

For multiple languages support, you can consider deploying several websites with their own domain names if you can afford additional maintenance, using Airbnb’s strategy for best SEO results.

Note that you can still use the same Stelace database and share assets across your localized websites.

You can also go for the single-domain route with several languages on the same website.

If you opt for a multi-language website, best strategy is to lazyload additional languages as they are needed during user navigation. Good news: it’s how we handle this in Stelace Instant templates.

Multi-currency

Exposing multiple currencies is another story and can confuse you users if not done right.

Only one currency should probably be shown to your users at a time. This template includes a $fx sample wrapper that could apply live exchange rate conversion in the app if assets have prices set in different currencies.

Exchange rates applied by your payment provider may be different though, and additional fees can apply, so you may want to warn your users about potential price changes unless you compensate exchange difference yourself or on the seller’s account.

Custom formats

You can use custom formats for date, time and number if needed, as per FormatJS docs using vue-intl:

const currencyFormat = {
  number: {
    customCurrency: {
      // currency: 'EUR',
      style: 'currency',
      minimumFractionDigits: 0
    }
  }
}

Vue.setLocale(lang)
Vue.registerFormats(lang, currencyFormat)

And then you can format with appropriate currency on the fly:

  {{ $formatNumber(asset.price, { format: 'customCurrency', currency: 'USD' }) }}

Should currency be set to EUR in currencyFormat format, you would still be able to override with USD.

You can also use these custom formats in translation files:

Discounted price is {{ price, number, customCurrency }}

Used libraries