Translation Guide
Translations Files
Translations are stored within the i18n/locales/
directory. The file name itself represents the locale (e.g., en_US.json
for the English (United States) locale, de_DE.json
for the German (Germany) locale). The translation keys are organized in a nested structure within these files, allowing for easy access and management of translations.
Key Naming Convention
- Casing: Use snake_case for all translation keys (e.g.,
product_details.add_to_cart
). - Structure: Follow a general
object.action
orsection.element.action
format. For instance,basket.checkout.confirm
orproduct_details.image_gallery.zoom
. - Naming: Refrain from using abbreviations in translation keys to ensure clarity and readability.
- Verbs: Use concise and descriptive verbs for action-related keys (e.g.,
add_to_cart
,view_details
,submit_form
). - Nouns: Use clear and specific nouns for elements and sections (e.g.,
product_name
,shipping_address
,order_summary
).
Namespacing and Structuring
- Component-Based Namespacing: Structure keys primarily around components. For instance, keys for a
ProductCard
component might includeproduct_card.title
,product_card.price
, andproduct_card.add_to_cart
. Pages are considered components as well. Since components can be reused across different locations, they might require distinct translations based on context. If a single translation cannot cover all scenarios, consider moving the translation to the parent component using<slot>
orprops
or adopting feature-based namespacing. - Feature-Based Namespacing: In addition to component-based namespacing, use feature-based namespacing to group keys related to a specific feature or functionality. This approach is particularly useful when a feature spans across multiple components or pages. For example, keys related to adding basket items might be prefixed with
basket.add_item
orbasket.remove_item
. This helps to organize translations around business capabilities rather than solely by component structure. - Dot Notation Hierarchy: Use dot notation to create hierarchical key structures that provide clear context. Examples:
product_detail_page.meta_data.title
,checkout.confirmation.message
. - Error Grouping: Consolidate all error-related translations under a dedicated
error
object. Use the error identifier (e.g., HTTP status code or business error key) as the translation key name. For example, within theadd_to_basket
feature:
Key Reuse vs. Context-Specific Keys
- Promote Key Reusability: Foster the reuse of keys for common elements, actions, and phrases throughout the application. This approach minimizes redundancy and streamlines translation management. The
global
namespace is ideal for housing such keys. Examples includeglobal.save
,global.cancel
, andglobal.loading
. Although shorter translations are more conducive to reuse and often find their way into theglobal
or a shared namespace, larger translations can also be shared when context permits. - Context-Specific Keys: Create context-specific keys when the same text requires different translations based on its location or usage within the UI. For instance, "Add" might be
product_detail_page.add_to_cart
on a product page butbasket_page.add_coupon
within the basket. - Avoid Duplicate Keys: Never create identical keys with different meanings. This leads to confusion and translation errors. If a key's meaning changes significantly, create a new, distinct key.
Placeholder Usage
- Dynamic Content: It is essential to use placeholders for dynamic content within translated strings. For instance,
Your order ({orderNumber}) has been confirmed.
This approach ensures that dynamic content is correctly inserted without compromising grammar across different languages. Concatenating translated strings with placeholder values in code should be avoided, as it can result in grammatical errors. - Placeholder Names: Utilize descriptive placeholder names that explicitly convey the content to be inserted. Employ camelCase for placeholder names to minimize the necessity of renaming variables when feeding them into the translation function. Example:
Your order ({orderNumber}) has been confirmed.
Pluralization
- Plural Forms: Use the
|
separator to define different plural forms in the same translation. Example:no apples | one apple | {count} apples
- All Cases: Always define all plural forms. By default,
@nuxtjs/i18n
/vue-i18n
supports three forms. No item, one item and many items. Example:no apples | one apple | {count} apples
. - Placeholder Usage: Use the predefined
{count}
placeholder when you want to reference the amount itself within the translation.
Using Translation Keys
- Translation Location: Whenever possible, confine the use of translations to the
<template>
section. Only translate in the<script>
or composables when you need to associate a value with a specific translation key. - Direct Key Usage: Always use the full translation key directly within the translation function (e.g.,
$t('product_details.add_to_cart')
ori18n.t('product_details.add_to_cart')
). This ensures clarity, makes the code easier to understand, and improves static analysis capabilities of tooling (e.g., linters can check for missing keys). - Avoid String Interpolation for Keys: Never construct translation keys dynamically using string interpolation or concatenation. This makes it significantly harder to track translations.
- Avoid Variables for Keys: While slightly better than string interpolation, avoid storing translation keys in variables unless absolutely necessary. This reduces code clarity.