Skip to main content

i18n-messaging

Manage and maintain i18n messaging or copy for Daedalus multi-language support.

Source facts

Repository
input-output-hk/daedalus
Last source activity
July 9, 2026 at 05:03
Detected SKILL.md language
English
Stars
1,247
Forks
296

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
i18n-messaging
description
Manage and maintain i18n messaging or copy for Daedalus multi-language support.
user-invocable
true
# i18n Messaging **Manage and maintain i18n messaging for Daedalus multi-language support** Handles message extraction, validation, localization workflows, and schema compliance for Daedalus's internationalization system. Supports English (en-US) and Japanese (ja-JP) locales using react-intl and Format.js. --- ## Message Schema Messages in Daedalus follow a structured format using `defineMessages()` from react-intl: ```typescript { messageKey: { id: "namespace.context.messageKey", // Unique identifier with dot notation defaultMessage: "!!!Message text with placeholders", description: "Context/description for translators", values?: Record<string, any> // Runtime variable placeholders } } ``` ### ID Naming Convention - **Format**: `namespace.context.messageKey` (dot-separated) - **Prefix**: All messages start with `!!!` in defaultMessage - **Examples**: - `global.errors.fieldIsRequired` - `api.errors.IncorrectPasswordError` - `global.ada.name` ### Variable Placeholders Messages with dynamic content use curly braces: ```typescript knownMnemonicWordCount: { id: 'global.info.knownMnemonicWordCount', defaultMessage: '!!!{actual} of {required} words entered', values: { actual: 5, required: 12 } } ``` --- ## Operations ### 1. Extract Messages Extract all i18n messages from source code to generate message catalog. ```bash yarn i18n:extract ``` **What it does**: - Scans `source/**/*.{ts,tsx}` files - Extracts `defineMessages()` and `<FormattedMessage />` calls - Ignores `.d.ts` TypeScript declaration files - Outputs to `translations/messages.json` - Records source file locations **When to use**: - After adding new messages with `defineMessages()` - Before running `i18n:check` - As part of `i18n:manage` workflow **Output format**: ```json [ { "path": "source/main/ipc/handlers.ts", "descriptors": [ { "id": "global.errors.fieldIsRequired", "defaultMessage": "!!!This field is required.", "description": "Error message when required fields are left empty." } ] } ] ``` ### 2. Check Translations Validate translation files for consistency and completeness against extracted messages. ```bash yarn i18n:check ``` **What it does**: - Compares extracted messages with translation files - Validates en-US and ja-JP locales - Ensures all message IDs are present - Detects missing or obsolete translations - Uses `react-intl-translations-manager` to manage lifecycle **When to use**: - After extracting new messages - Before committing translation changes - To validate message format across locales **Validates**: - All en-US messages have corresponding ja-JP translations - No orphaned message IDs - Message structure consistency (id, defaultMessage, description) ### 3. Manage Translations Combined operation: extract messages AND validate translations in one command. ```bash yarn i18n:manage ``` **Equivalent to**: `yarn i18n:extract && yarn i18n:check` **When to use**: - Primary workflow for updating i18n content - Part of `check:all` verification - Before creating commits with messaging changes --- ## Supported Locales | Locale | Language | Directory | |---------|----------|-------------------------------------------| | en-US | English | `source/renderer/app/i18n/locales/en-US.json` | | ja-JP | Japanese | `source/renderer/app/i18n/locales/ja-JP.json` | ### Locale Files Structure ``` source/renderer/app/i18n/locales/ ├── defaultMessages.json # All extracted messages (auto-generated) ├── en-US.json # English translations (English only) ├── ja-JP.json # Japanese translations ├── whitelist_en-US.json # Approved en-US messages ├── whitelist_ja-JP.json # Approved ja-JP messages └── terms-of-use/ # Locale-specific documents ``` --- ## Best Practices ### Adding New Messages 1. Use `defineMessages()` or `<FormattedMessage />` in source code 2. Follow naming convention: `namespace.context.messageKey` 3. Include descriptive `description` for translators 4. Always prefix defaultMessage with `!!!` 5. Run `yarn i18n:extract` to register new messages ### Validating Message IDs **Do**: - Use hierarchical namespaces: `wallet.send.confirmButton` - Keep IDs consistent across related messages - Document placeholder variables in description - Use lowercase with dots as separators **Don't**: - Use spaces or special characters in IDs - Duplicate IDs across features - Leave placeholders undocumented - Change ID format mid-project ### Working with Placeholders Messages with runtime values use curly braces: ```typescript // Define message with placeholder notEnoughFunds: { id: 'wallet.errors.notEnoughFunds', defaultMessage: '!!!Remaining balance: {balance} ADA', description: 'Error when insufficient funds' } // Use at runtime <FormattedMessage id="wallet.errors.notEnoughFunds" defaultMessage="Remaining balance: {balance} ADA" values={{ balance: walletBalance }} /> ``` ### Translation Flow 1. **Extract**: Run `yarn i18n:extract` after code changes 2. **Check**: Run `yarn i18n:check` to validate 3. **Review**: Update localized JSON files as needed 4. **Verify**: Run `check:all` before committing 5. **Commit**: Include updated `translations/messages.json` and locale files ### Generated `!!!` Placeholders - `yarn i18n:manage` seeds missing locale entries from `defaultMessage`, so new keys in `en-US.json` and `ja-JP.json` can be written with the `!!!` prefix. - Treat `!!!` in locale files as a new or untranslated message marker, not polished release copy. - This workflow does not remove the prefix automatically. If locale polish is in scope, manually replace new `en-US.json` entries with approved English copy and add real Japanese translations in `ja-JP.json` before commit. - If the task only covers extraction or catalog sync, keeping generated `!!!` placeholders is acceptable, but document the follow-up translation work explicitly. --- ## Related Files | File | Purpose | |------|---------| | `translations/translation-runner.ts` | Validates translations (manages mapping) | | `translations/formatter.js` | Custom extraction format for Format.js | | `translations/messages.json` | Extracted message catalog | | `source/renderer/app/i18n/global-messages.ts` | Global message definitions | | `source/renderer/app/i18n/errors.ts` | Error message definitions | | `source/renderer/app/i18n/types.ts` | TypeScript types for messages | --- ## Troubleshooting ### Messages not extracted - Verify `defineMessages()` is imported from `react-intl` - Check files are in `source/**/*.{ts,tsx}` (not .d.ts) - Run `yarn clear:translations` then `yarn i18n:extract` ### Translation validation fails - Ensure all en-US messages have ja-JP equivalents - Check message IDs match exactly (case-sensitive) - Verify JSON format is valid in locale files ### Missing or duplicate IDs - Check for conflicting message keys across files - Remove obsolete messages from translation files manually - Re-run `yarn i18n:manage` to refresh state --- ## Template: Adding New Message ```typescript import { defineMessages } from 'react-intl'; // In your component file or messages.ts export const componentMessages = defineMessages({ newMessageKey: { id: 'feature.component.newMessageKey', defaultMessage: '!!!Default English text', description: 'Context for translators explaining where/how this message is used', }, messageWithPlaceholder: { id: 'feature.component.messageWithPlaceholder', defaultMessage: '!!!You have {count} items', description: 'Message showing item count with placeholder', }, }); ``` Then run: `yarn i18n:manage`
View on GitHub