
Typo3 Translations
- 13 installs
- 33 repo stars
- Updated July 27, 2026
- dirnbauer/webconsulting-skills
Manage TYPO3 13/14 localization with XLIFF 1.2/2.0, ICU messages, LLL references, and v14 translation-domain migration.
About
This skill guides TYPO3 13/14 localization with XLIFF files, ICU MessageFormat, LLL references, and translation domains. A developer uses it when handling TYPO3 translations, labels, missing or duplicate keys, or v13-to-v14 translation migration.
- Guides locallang.xlf, labels.xlf, XLIFF 1.2/2.0, ICU MessageFormat, and LLL references
- Covers translation domains, Content Blocks labels, and v13-to-v14 migration checks
Typo3 Translations by the numbers
- 13 all-time installs (skills.sh)
- Ranked #1,103 of 1,879 Documentation skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dirnbauer/webconsulting-skills --skill typo3-translationsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| repo stars | ★ 33 |
| Last updated | July 27, 2026 |
| Repository | dirnbauer/webconsulting-skills ↗ |
What it does
Manage TYPO3 13/14 localization with XLIFF 1.2/2.0, ICU messages, LLL references, and v14 translation-domain migration.
Files
TYPO3 13/14 Translations
Source: https://github.com/dirnbauer/webconsulting-skills
Use this skill for TYPO3 13 and TYPO3 14 translation files, XLIFF format decisions, localization keys, ICU strings, LLL: references, and v14 translation-domain adoption. Start from the TYPO3 13-compatible baseline, then apply TYPO3 14 upgrades when the extension or project is v14-only.
Core Rules
- For TYPO3 13+14 compatibility, keep XLIFF 1.2 and full
LLL:EXT:
references.
- For TYPO3 14-only work, prefer XLIFF 2.0 and consider translation domains in
PHP where they improve readability.
- Keep one source language file in English, unprefixed, for example
Resources/Private/Language/locallang.xlf or labels.xlf.
- Store target languages beside the source with locale prefixes, for example
de.locallang.xlf, de_CH.locallang.xlf, or de.labels.xlf.
- Do not create
en.locallang.xlf; English is the unprefixed source. - Keep exactly one
<file>element per XLIFF file. - Keep one target language per target file.
- Mark approved translations with
approved="yes"in XLIFF 1.2 or
state="reviewed" / state="final" in XLIFF 2.0.
- Treat ICU MessageFormat as TYPO3 14.2+ only; do not use ICU for code that
must run unchanged on TYPO3 13.
- Use TYPO3 localization APIs and Fluid ViewHelpers; do not add custom label
loaders.
Default Workflow
1. Inventory source files in Resources/Private/Language/*.xlf and ContentBlocks/**/language/*.xlf. 2. Inventory consumers in PHP, TCA, YAML, Fluid, TypoScript, TSconfig, and Content Blocks configuration. 3. Decide the compatibility mode:
- TYPO3 13+14: stay on XLIFF 1.2 and
LLL:EXT:. - TYPO3 14-only: migrate selected catalogs to XLIFF 2.0 and optionally use
domains/ICU. 4. Normalize paths, filenames, XML namespaces, and key namespaces. 5. Add or migrate labels with natural target-language copy. 6. Validate XML, duplicate IDs, source/target parity, and LLL: resolution. 7. Flush TYPO3 caches and smoke-test backend and frontend language contexts.
TYPO3 13-Compatible Baseline
Use this baseline when an extension must support TYPO3 13 and 14.
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="EXT:my_extension/Resources/Private/Language/locallang.xlf" product-name="my_extension">
<header/>
<body>
<trans-unit id="button.save">
<source>Save</source>
</trans-unit>
<trans-unit id="items.count">
<source>Items: %d</source>
</trans-unit>
</body>
</file>
</xliff>Target file:
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" target-language="de" datatype="plaintext" original="EXT:my_extension/Resources/Private/Language/locallang.xlf" product-name="my_extension">
<header/>
<body>
<trans-unit id="button.save" approved="yes">
<source>Save</source>
<target>Speichern</target>
</trans-unit>
<trans-unit id="items.count" approved="yes">
<source>Items: %d</source>
<target>Eintraege: %d</target>
</trans-unit>
</body>
</file>
</xliff>TYPO3 13 notes:
- Use
source-language="en"andtarget-language="<locale>". - Use
<trans-unit>inside<body>. - Use
approved="yes"for reviewed translations when approval state matters. - Use
%s/%dstyle placeholders and runtime formatting, not ICU. - Use full
LLL:EXT:references; translation domains are a TYPO3 14 feature.
TYPO3 14 Changes
Use these changes when the project is TYPO3 14-only, or when preparing a v14 branch while keeping the v13 branch on the baseline above.
XLIFF 2.0
Use this source shape for v14-only catalogs:
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en">
<file id="messages">
<unit id="button.save">
<segment>
<source>Save</source>
</segment>
</unit>
<unit id="items.count">
<segment>
<source>{count, plural, one {# item} other {# items}}</source>
</segment>
</unit>
</file>
</xliff>Use this target shape:
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en" trgLang="de">
<file id="messages">
<unit id="button.save">
<segment state="final">
<source>Save</source>
<target>Speichern</target>
</segment>
</unit>
<unit id="items.count">
<segment state="final">
<source>{count, plural, one {# item} other {# items}}</source>
<target>{count, plural, one {# Eintrag} other {# Eintraege}}</target>
</segment>
</unit>
</file>
</xliff>Migrating XLIFF 1.2 To 2.0
Use this checklist only after the affected label family no longer needs TYPO3 13 compatibility:
1. Confirm composer.json and ext_emconf.php no longer support TYPO3 13. 2. Create a branch and convert one label family first. 3. Change <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> to <xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en">. 4. Remove the XLIFF 1.2 <header> and <body> wrapper. 5. Convert each <trans-unit id="key"> to <unit id="key"><segment>.... 6. Move <source> and <target> inside <segment>. 7. Convert source-language/target-language attributes to srcLang/trgLang. 8. Convert approved="yes" to state="reviewed" or state="final". 9. Split files that contain more than one <file> or more than one target language. 10. Preserve unit IDs exactly; change references only when deliberately renaming keys. 11. Validate XML and compare unit IDs between source and every target file. 12. Flush TYPO3 caches and verify labels in all affected backend/frontend views.
Do not migrate to a newer XLIFF dialect just because tooling can emit it. For a TYPO3 14-only branch, use the documented XLIFF 2.0 shape unless the project has verified support for another 2.x variant.
ICU MessageFormat
TYPO3 14.2+ supports ICU MessageFormat when translation calls pass named arguments. Store ICU strings as normal XLIFF source and target text.
For TYPO3 13+14 compatibility, avoid ICU and keep classic placeholders. Add ICU only in v14-only code paths or v14-only label files.
Rules:
- Use named placeholders such as
{count}and{name}. - Do not translate placeholder names.
- Include
otherin everypluralandselectexpression. - Test plural messages with
0,1, and multiple values. - Use
LanguageService::translate(),LocalizationUtility::translate(), or
Fluid <f:translate arguments="{...}">; sL() resolves plain labels only.
PHP:
$label = $languageService->translate(
'items.count',
'my_extension.messages',
['count' => 5],
);Fluid:
<f:translate key="items.count" arguments="{count: itemCount}" />Paths, Namespaces, And Domains
Use stable file paths and key namespaces so references remain readable during v13-to-v14 upgrades.
File Paths
- Shared extension labels:
EXT:my_extension/Resources/Private/Language/messages.xlf
- Traditional extension labels:
EXT:my_extension/Resources/Private/Language/locallang.xlf
- Database/TCA labels:
EXT:my_extension/Resources/Private/Language/locallang_db.xlf
- Content Blocks labels:
ContentBlocks/<Type>/<name>/language/labels.xlf
Use full LLL:EXT: references where configuration is loaded outside an Extbase context:
'label' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang_db.xlf:tx_my_table.title',XML Namespace
Use the XLIFF 2.0 namespace exactly:
xmlns="urn:oasis:names:tc:xliff:document:2.0"XLIFF IDs Versus TYPO3 14 Domains
Keep the XLIFF unit ID independent from the file/domain reference:
- XLIFF unit ID:
top,button.save,field.ctaText.label. - TYPO3 14 domain:
my_extension.messages,my_extension.label,
my_extension.backend.dashboard.
- Combined v14 reference:
my_extension.label:top.
Do not write my_extension.label.top when you mean a TYPO3 14 domain reference. Without the colon, it is just a dotted label ID in the current Extbase/default context.
TYPO3 14 derives domains from language file paths:
| File | Domain |
|---|---|
Resources/Private/Language/locallang.xlf | my_extension.messages |
Resources/Private/Language/messages.xlf | my_extension.messages |
Resources/Private/Language/label.xlf | my_extension.label |
Resources/Private/Language/locallang_label.xlf | my_extension.label |
Resources/Private/Language/Backend/locallang_dashboard.xlf | my_extension.backend.dashboard |
Configuration/Sets/Blog/labels.xlf | my_extension.sets.blog |
If two files map to the same domain, such as label.xlf and locallang_label.xlf, the simplified filename wins. Avoid these conflicts.
TYPO3 14 Fluid And API Syntax
Use domains for v14-only Fluid templates:
<f:translate domain="my_extension.label" key="top" />
<f:translate key="my_extension.label:top" />
{f:translate(domain: 'my_extension.messages', key: 'button.save')}Use the same combined syntax in PHP:
$languageService->sL('my_extension.label:top');
$languageService->sL('my_extension.messages:button.save');For TYPO3 13 compatibility, keep:
<f:translate key="top" extensionName="MyExtension" />
<f:translate key="LLL:EXT:my_extension/Resources/Private/Language/label.xlf:top" />The v14 domain argument takes precedence over extensionName. Inspect domains with php bin/typo3 language:domain:list when EXT:lowlevel is available.
TYPO3 API First
Use LanguageServiceFactory when a language service must be created explicitly.
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
final readonly class LabelService
{
public function __construct(
private LanguageServiceFactory $languageServiceFactory,
) {}
public function saveLabel(ServerRequestInterface $request): string
{
$languageService = $this->languageServiceFactory->createFromSiteLanguage(
$request->getAttribute('language'),
);
return $languageService->sL(
'LLL:EXT:my_extension/Resources/Private/Language/messages.xlf:button.save',
);
}
}For backend-only code, $GLOBALS['LANG'] can be used when the backend bootstrap has initialized it. Keep access wrapped in a helper so the dependency is obvious.
Content Blocks Labels
Content Blocks labels commonly live beside the block in ContentBlocks/<Type>/<name>/language/labels.xlf. The source file is labels.xlf; translated files use locale prefixes such as de.labels.xlf.
1. Put editor-facing title and description in the block language file. 2. Use field IDs such as <field>.label and <field>.description. 3. Generate or inspect expected keys before editing:
vendor/bin/typo3 content-blocks:language:generate vendor/block --print
vendor/bin/typo3 content-blocks:language:generate vendor/block --extension=my_extension4. Remember that labels.xlf overrides inline labels from config.yaml. 5. Convert generated v14-only catalogs to XLIFF 2.0 after the key list is known.
Detailed Reference
Read the full guide when the task needs detailed examples, long templates, troubleshooting matrices, appendices, or sections not included above. Keep this file unloaded for narrow tasks so the skill follows progressive disclosure.
interface:
display_name: "TYPO3 13/14 Translations"
short_description: "TYPO3 13/14 XLIFF, ICU, and labels"
default_prompt: "Use $typo3-translations to audit my TYPO3 13/14 translation files and plan safe TYPO3 14 XLIFF 2.0 or ICU upgrades."
policy:
allow_implicit_invocation: true
Common Pitfalls
Continues typo3-translations from full guide.
Common Pitfalls
| Symptom | Likely Cause | First Fix |
|---|---|---|
Raw LLL:EXT: appears | Wrong path, filename, extension key, or unit ID | Copy the exact installed path, parse XML, flush caches |
| English fallback appears | Missing or wrongly named target file | Place de.*.xlf beside the source and set trgLang="de" |
| German target is ignored | Target segment is unapproved | Use state="reviewed" or state="final" |
| ICU plural stays literal | Fetched with sL() or positional arguments | Use translate() or Fluid named arguments |
| Domain resolves wrong file | Filename conflict or stale cache | Rename conflicting files and clear cache.l10n |
| Content Blocks inline label is ignored | labels.xlf takes precedence | Edit or regenerate the block language file |
| XLIFF 2.0 breaks TYPO3 13 | XLIFF 2.0 is a TYPO3 14 feature | Keep shared branches on XLIFF 1.2 |
| Translation domain breaks | Domain syntax used in TYPO3 13-compatible code | Use full LLL:EXT: until v14-only |
FAQ
Continues typo3-translations from full guide.
FAQ
Should I start with TYPO3 13 or TYPO3 14?
Start with the TYPO3 13-compatible baseline when the extension must support both 13 and 14. Move selected label families to TYPO3 14 patterns only when the code or branch is v14-only.
Should I use XLIFF 2.0 or 1.2?
Use XLIFF 1.2 for TYPO3 13+14 compatibility. Use XLIFF 2.0 for new v14-only work.
What is the latest XLIFF format to use here?
For TYPO3 13 compatibility, use XLIFF 1.2. For TYPO3 14-only catalogs, use the documented XLIFF 2.0 structure.
Should I create `en.locallang.xlf`?
No. The unprefixed file is the English source. Use prefixes only for target languages.
Are `LLL:EXT:` references deprecated?
No. TYPO3 14 adds translation domains as a shorter option, but full file-based references remain valid and useful.
When should I use translation domains?
Use them in PHP when shorter references improve readability. Use explicit LLL:EXT: paths where configuration benefits from showing the exact file.
Can I use ICU MessageFormat in XLIFF 2.0?
Yes, in TYPO3 14.2+ only. For TYPO3 13-compatible code, keep classic placeholders and runtime formatting.
Why does `state="translated"` not show?
TYPO3 loads approved localizations by default. Use state="reviewed" or state="final" for reviewed target strings.
Can one XLIFF file contain multiple target languages?
No. Keep one target language per file.
Are translation files for editorial content?
No. XLIFF files are for UI labels and short runtime messages. Editorial content belongs in TYPO3 records and site localization.
typo3-translations Full Guide
Read only the section that matches the current task. These files continue the main SKILL.md after its lightweight workflow and examples.
Sections
- Updating TYPO3 13 To TYPO3 14
- What To Do If Something Fails
- Common Pitfalls
- Verification Commands
- Quality Bar
- FAQ
- Official Sources
Official Sources
Continues typo3-translations from full guide.
Official Sources
- TYPO3 Explained: XLIFF format
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Localization/XliffFormat.html
- TYPO3 Core changelog: ICU MessageFormat support
https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/14.2/Feature-104546-SupportICUMessageFormatForPluralForms.html
- TYPO3 Core changelog: Translation domain mapping
https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/14.0/Feature-93334-TranslationDomainMapping.html
- TYPO3 Fluid Translate ViewHelper
https://docs.typo3.org/other/typo3/view-helper-reference/main/en-us/Global/Translate.html
- TYPO3 Content Blocks language files
https://docs.typo3.org/p/friendsoftypo3/content-blocks/main/en-us/Definition/Language/Index.html
Quality Bar
Continues typo3-translations from full guide.
Quality Bar
- The skill starts with TYPO3 13-compatible output unless the task is clearly
v14-only.
- TYPO3 14 output is preferred when compatibility constraints allow it.
- Shared TYPO3 13+14 branches stay on XLIFF 1.2 and
LLL:EXT:. - New or converted v14-only label files use the XLIFF 2.0 structure
intentionally.
- Source and target files stay structurally aligned.
- Keys are stable, namespaced, and readable.
- ICU strings keep placeholder names intact and use named runtime arguments.
- TYPO3 APIs resolve labels; no custom XML label loader is introduced.
- All changed files parse as XML and labels are smoke-tested after cache flush.
Updating TYPO3 13 To TYPO3 14
Continues typo3-translations from full guide.
Updating TYPO3 13 To TYPO3 14
Use this translation-specific checklist during a TYPO3 13-to-14 upgrade:
1. Keep XLIFF 1.2 and LLL:EXT: references while the same branch must support both TYPO3 13 and 14. 2. Run Rector/Fractor and the project upgrade checklist from typo3-update. 3. Inventory all .xlf files and note their versions, language prefixes, and consumers. 4. Fix invalid XML and duplicate IDs before format conversion. 5. Replace hardcoded labels with LLL:EXT: or domain references. 6. Convert label families from XLIFF 1.2 to XLIFF 2.0 only in a v14-only branch. 7. Keep LLL:EXT: references unless a domain migration is explicitly part of the task. 8. Add ICU only in v14-only runtime code; do not rewrite plain labels into ICU strings. 9. Validate source/target parity for every locale. 10. Flush caches, run backend smoke tests, and verify frontend locale rendering.
Verification Commands
Continues typo3-translations from full guide.
Verification Commands
# XML well-formedness
find Resources ContentBlocks -name '*.xlf' -print0 2>/dev/null | xargs -0 -n1 xmllint --noout
# XLIFF versions
rg -n '<xliff version=' Resources ContentBlocks -S
# Translation consumers
rg -n 'LLL:|f:translate|translate\\(|sL\\(' Classes Configuration ContentBlocks Resources -S
# TYPO3 14 translation domains, when EXT:lowlevel is installed
php bin/typo3 language:domain:listIf xmllint is unavailable, use the project PHP runtime with DOMDocument to parse changed files.
What To Do If Something Fails
Continues typo3-translations from full guide.
What To Do If Something Fails
Use this checklist before changing code paths:
1. Parse every changed .xlf file as XML. 2. Confirm the source file is unprefixed English and the target file is prefixed. 3. Confirm version-specific language attributes: source-language / target-language for XLIFF 1.2, srcLang / trgLang for XLIFF 2.0. 4. Confirm every referenced unit ID exists exactly once. 5. Confirm target files contain matching unit IDs and approved target segments. 6. Confirm the LLL:EXT: path uses the extension key, not the Composer package. 7. Clear TYPO3 caches, including localization/domain mapping caches. 8. If domains are used, verify the project is v14-only, run language:domain:list, and check filename conflicts. 9. If ICU does not interpolate, verify the project is v14.2+, named arguments are passed, and translate() is used. 10. If Content Blocks labels differ from YAML, inspect labels.xlf first. 11. Reproduce in the correct language context; backend user language and site language can differ. 12. Revert only the smallest recent translation change when isolating a failure.