Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,12 +340,12 @@ To add a new locale:
5. If the language is `right-to-left`, add `dir: 'rtl'` (see `ar-EG` in config for example)
6. If the language requires special pluralization rules, add a `pluralRule` callback (see `ar-EG` or `ru-RU` in config for examples)

Check [Pluralization rule callback](https://vue-i18n.intlify.dev/guide/essentials/pluralization.html#custom-pluralization) for more info.
Check [Pluralization rule callback](https://vue-i18n.intlify.dev/guide/essentials/pluralization#custom-pluralization) and [Plural Rules](https://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Determining-Plural-Categories) for more info.

### Update translation

We track the current progress of translations with [Lunaria](https://lunaria.dev/) on this site: https://i18n.npmx.dev/
If you see any outdated translations in your language, feel free to update the keys to match then English version.
If you see any outdated translations in your language, feel free to update the keys to match the English version.

In order to make sure you have everything up-to-date, you can run:

Expand Down Expand Up @@ -408,13 +408,51 @@ See how `es`, `es-ES`, and `es-419` are configured in [config/i18n.ts](./config/
<p>{{ $t('greeting', { name: userName }) }}</p>
```

4. Don't concatenate string messages in the Vue templates, some languages can have different word order. Use placeholders instead.

**Bad:**

```vue
<p>{{ $t('hello') }} {{ userName }}</p>
```

**Good:**

```vue
<p>{{ $t('greeting', { name: userName }) }}</p>
```

**Complex content:**

If you need to include HTML or components inside the translation, use [`i18n-t`](https://vue-i18n.intlify.dev/guide/advanced/component.html) component. This is especially useful when the order of elements might change between languages.

```json
{
"agreement": "I accept the {terms} and {privacy}.",
"terms_link": "Terms of Service",
"privacy_policy": "Privacy Policy"
}
```

```vue
<i18n-t keypath="agreement" tag="p">
<template #terms>
<NuxtLink to="/terms">{{ $t('terms_link') }}</NuxtLink>
</template>
<template #privacy>
<strong>{{ $t('privacy_policy') }}</strong>
</template>
</i18n-t>
```

### Translation key conventions

- Use dot notation for hierarchy: `section.subsection.key`
- Keep keys descriptive but concise
- Group related keys together
- Use `common.*` for shared strings (loading, retry, close, etc.)
- Use component-specific prefixes: `package.card.*`, `settings.*`, `nav.*`
- Do not use dashes (`-`) in translation keys; always use underscore (`_`): e.g., `privacy_policy` instead of `privacy-policy`

### Using i18n-ally (recommended)

Expand Down
Loading