Stelace Instant template includes English (default) and French translations out of the box, and can be translated to many more languages.
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.
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.
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 🚀.
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.
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.
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
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
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.
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.
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.
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.
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.
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.
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 }}
- vue-intl
- i18n-compile internally, to compile user-friendly .yaml into .json files.