skill-translate
AL translation and localization for Business Central. Use when working with XLF files, NAB tools, or implementing multi-language support in extensions.
Works with
Agent Skills format with YAML frontmatter. Claude Code reads it as-is.
---
name: "skill-translate"
description: "AL translation and localization for Business Central. Use when working with XLF files, NAB tools, or implementing multi-language support in extensions."
license: "MIT"
---
# Skill: AL Translation Management
## Purpose
Manage multilingual translations for AL extensions using XLF files: create and refresh language files, batch-translate with NAB AL Tools, preserve placeholders, enforce character limits, maintain terminology consistency, and implement quality review workflows.
## When to Load
This skill should be loaded when:
- A new target language needs to be added to an AL extension
- Untranslated texts need to be translated after code changes
- Translation quality review is needed (placeholder validation, character limits)
- Regional language variations must be managed (es-ES vs es-MX)
- Incremental translation is required after refreshing XLF files
## Core Patterns
### Pattern 1: Create Language File
Create a new XLF translation file from the generated source:
```
createLanguageXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
targetLanguageCode: "es-ES"
matchBaseAppTranslation: true // pre-populate from Microsoft base translations
```
**Rules:**
- The `.g.xlf` file is auto-generated by the AL compiler — never edit it manually
- `matchBaseAppTranslation: true` copies existing Microsoft translations for standard terms
- One language file per locale: `MyApp.es-ES.xlf`, `MyApp.fr-FR.xlf`, etc.
### Pattern 2: Refresh and Retrieve Texts
After code changes, sync the language file and get new untranslated texts:
```
// Step 1: Refresh — adds new entries, preserves existing translations
refreshXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
filePath: "Translations/MyApp.es-ES.xlf"
// Step 2: Get untranslated texts with context
getTextsToTranslate
filePath: "Translations/MyApp.es-ES.xlf"
limit: 50
offset: 0
```
Each text entry includes:
- `id` — unique identifier for the translation unit
- `source` — original text to translate
- `type` — context: `Table Customer - Field Name - Property Caption`
- `maxLength` — character limit (if set in AL source)
- `comments` — notes about placeholders (%1, %2)
### Pattern 3: Batch Translation
Translate multiple texts in a single operation:
```
saveTranslatedTexts
filePath: "Translations/MyApp.es-ES.xlf"
translations: [
{
"id": "Table_ContosoProject_Field_Description_Caption",
"targetText": "Descripción",
"targetState": "translated"
},
{
"id": "Page_ContosoProjectCard_Action_Release_Caption",
"targetText": "Lanzar",
"targetState": "translated"
},
{
"id": "Codeunit_ContosoMgt_Error_CustomerNotFound",
"targetText": "Cliente %1 no encontrado.",
"targetState": "translated"
}
]
```
**Translation rules:**
1. **Preserve placeholders** — `%1`, `%2`, `%3` must appear in the same order
2. **Respect `maxLength`** — abbreviate if needed, never exceed
3. **Match context** — same English word may have different translations depending on `type`
4. **Follow Microsoft terminology** — use base app translations for standard BC terms
### Pattern 4: Translation Quality Review
Use translation states to implement a review workflow:
| State | Meaning | Who |
|---|---|---|
| `translated` | Initial translation done | Translator |
| `needs-review-translation` | Flagged for review | Translator / QA |
| `final` | Reviewed and approved | Reviewer |
| `signed-off` | Production-ready | Language lead |
```
// Find texts needing review
getTranslatedTextsByState
filePath: "Translations/MyApp.es-ES.xlf"
translationStateFilter: "needs-review-translation"
limit: 0
// After review, promote to final
saveTranslatedTexts
filePath: "Translations/MyApp.es-ES.xlf"
translations: [
{ "id": "...", "targetText": "...", "targetState": "final" }
]
```
**Common quality issues:**
```
// Issue 1: Missing placeholder
❌ Source: "Posted %1 of %2"
❌ Translation: "Registrado %2" // missing %1
✅ Translation: "Registrado %1 de %2"
// Issue 2: Character limit exceeded
❌ Source: "Post" (maxLength: 10)
❌ Translation: "Registrar y contabilizar" // 25 chars
✅ Translation: "Registrar" // 9 chars
// Issue 3: Context-dependent meaning
Source: "Post"
Context: Action caption → "Registrar" ✅
Context: Table name → "Correo" ✅ (different meaning!)
```
### Pattern 5: Translation Memory and Glossary
Use existing translations for consistency:
```
// Get all translated texts as a reference map
getTranslatedTextsMap
filePath: "Translations/MyApp.es-ES.xlf"
limit: 0
// Search for specific terms across translations
getTextsByKeyword
filePath: "Translations/MyApp.es-ES.xlf"
keyword: "Customer|Vendor|Invoice"
isRegex: true
caseSensitive: false
searchInTarget: true
```
**Glossary approach:**
- Before translating a batch, retrieve existing translations with `getTranslatedTextsMap`
- Search for related terms with `getTextsByKeyword` to ensure consistent terminology
- Standard BC terms should match Microsoft's official base app translations
### Pattern 6: Regional Variations
Manage locale-specific translations (e.g., es-ES vs es-MX):
```
// Step 1: Create base translation (es-ES)
createLanguageXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
targetLanguageCode: "es-ES"
matchBaseAppTranslation: true
// Step 2: Create regional variant from base
createLanguageXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
targetLanguageCode: "es-MX"
matchBaseAppTranslation: true
// Step 3: Get base translations as reference
getTranslatedTextsMap
filePath: "Translations/MyApp.es-ES.xlf"
limit: 0
// Step 4: Copy base, then adjust regional terms
// "Ordenador" (es-ES) → "Computadora" (es-MX)
// "Factura" stays the same in both
```
## Workflow
### Step 1: Setup
1. Build the extension to generate the `.g.xlf` file: `al_build`
2. Create language file for each target locale (Pattern 1)
3. If language files already exist, refresh them (Pattern 2)
### Step 2: Translate
1. Retrieve untranslated texts with `getTextsToTranslate` (paginate with `limit`/`offset`)
2. Check translation memory for consistency (Pattern 5)
3. Translate in batches of 20-50 items (Pattern 3)
4. Save progress frequently — use `targetState: "translated"`
### Step 3: Review
1. Retrieve texts by state: `getTranslatedTextsByState` with `"translated"` filter
2. Validate:
- All placeholders preserved (`%1`, `%2`, etc.)
- Character limits respected
- Context-appropriate translations
- Consistent terminology across the extension
3. Mark reviewed texts: `targetState: "needs-review-translation"` → `"final"`
### Step 4: Finalize
1. Verify no untranslated texts remain: `getTextsToTranslate` with `limit: 0`
2. Promote all `final` texts to `signed-off`
3. Build the extension to verify XLF integration: `al_build`
4. Test the UI in the target language
## Common Language Codes
| Code | Language | Code | Language |
|---|---|---|---|
| `es-ES` | Spanish (Spain) | `fr-FR` | French (France) |
| `es-MX` | Spanish (Mexico) | `fr-CA` | French (Canada) |
| `de-DE` | German | `pt-BR` | Portuguese (Brazil) |
| `it-IT` | Italian | `nl-NL` | Dutch |
| `da-DK` | Danish | `sv-SE` | Swedish |
| `nb-NO` | Norwegian | `fi-FI` | Finnish |
| `pl-PL` | Polish | `cs-CZ` | Czech |
| `ja-JP` | Japanese | `zh-CN` | Chinese (Simplified) |
## References
- [Working with Translation Files](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-work-with-translation-files)
- [NAB AL Tools Extension](https://marketplace.visualstudio.com/items?itemName=nabsolutions.nab-al-tools)
- [XLIFF 1.2 Standard](http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html)
- [MaxLength Property](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/properties/devenv-maxlength-property)
## Constraints
- This skill covers **XLF translation management, batch translation, and quality review workflows**
- Do NOT edit `.g.xlf` files manually — they are compiler-generated
- Do NOT remove or reorder placeholders (`%1`, `%2`) in translations
- Do NOT exceed `maxLength` character limits defined in AL source
- Do NOT translate without checking existing translation memory first (consistency)
- Translation testing in UI → `skill-testing.md` | Page captions and tooltips → `skill-pages.md`More General & Other skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.

