Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Business Central is multi-language enabled, which means that you can display the user interface (UI) in different languages. In Business Central, this is done using XLIFF files, which is a standardized format used for computer-based translations.
Important
We're announcing the deprecation of the Dynamics 365 Translation Service (DTS). This service will reach end-of-support on October 15, 2025, and will no longer be available after this date. For more information go here.
Tip
Optionally, use the Dynamics 365 Translation Service to get translations for your target languages. For more information, see Translate user interface files.
For an overview of how translations are applied, see Translations overview.
Generating the XLIFF file
To add a new language to the extension that, you've built, first, you must enable the generation of XLIFF files. The XLIFF file extension is .xlf. The generated XLIFF file contains the strings that are specified in properties such as Caption, CaptionML, and Tooltip.
Note
To submit an app to Marketplace, you must use XLIFF translation files.
In the app.json file of your extension, add the following line:
"features": [ "TranslationFile" ]
Note
If the Incremental Build setting is enabled in the AL Language extension configuration then all translations will be ignored, even though the "features": [ "TranslationFile" ] setting is specified in the app.json file. For more information, see AL Language Extension Configuration.
The same is true when using RAD publishing, all translations will also be ignored. For more information, see Work with Rapid Application Development.
Now, when you run the build command (Ctrl+Shift+B) in Visual Studio Code, a \Translations folder is generated and populated with the .xlf file that contains all the labels, label properties, and report labels that you're using in the extension. The generated .xlf file can now be translated.
Important
The ML versions of properties are not included in the .xlf file:
- AboutTitleML
- AboutTextML
- CaptionML
- InstructionalTextML
- OptionCaptionML
- PromotedActionCategoriesML
- RequestFilterHeadingML
- ToolTipML
The TextConst data type is not included in the .xlf file either.
Important
Make sure to rename the translation file before building the extension next time, as it'll be overwritten.
By setting the GenerateCaptions flag in the app.json file, you specify that you want to generate captions based on the object name for pages, tables, reports, XMLports, and request pages. If the object already has a Caption property set, that value is used. For the table fields, the OptionCaption is used. The syntax is as follows:
"features": [ "TranslationFile", "GenerateCaptions" ]
GenerateLockedTranslations
APPLIES TO: Business Central 2020 release wave 2 and later
By setting the GenerateLockedTranslations flag in the app.json file, you specify that you want to generate <trans-unit> elements for locked labels in the XLIFF file. The default behavior is that these elements aren't generated. For more information, see JSON Files.
"features": [ "GenerateLockedTranslations" ]
Include namespaces in translation IDs
APPLIES TO: Business Central 2026 release wave 2 and later
Use the TranslationsWithNamespaces compiler feature to include an object's namespace in generated translation IDs. The compiler also uses readable object, member, and property names instead of hashed values when the generated ID is 400 characters or fewer. Namespace-aware IDs prevent collisions between objects that have the same name in different namespaces. They also make translation entries easier to identify.
The feature requires runtime version 18.0 or later and the TranslationFile feature. Learn more in Choose runtime version in AL. Add both features to the features setting in the app.json file:
"features": [ "TranslationFile", "TranslationsWithNamespaces" ]
For example, the generated translation ID for a page caption changes from:
Page 1066360047 - Property 2879900210
to:
Namespace MyNamespace.MyProductArea - Page SamplePage - Property Caption
If an object doesn't have a namespace, the compiler omits the namespace component but still uses readable names. If the readable ID would exceed 400 characters, the compiler generates a namespace-aware hashed ID instead.
Enabling this feature changes the IDs in newly generated XLIFF files. The compiler can consume both legacy and namespace-aware IDs, so existing translation files remain valid.
Enabling TranslationsWithNamespaces doesn't by itself trigger AppSourceCop rule AS0125. You can also add a namespace to an object that previously had none without triggering the rule if nothing else that affects its translation IDs changes. Moving a namespace, removing a namespace, or renaming an object or member are still breaking changes. Learn more in AppSourceCop Info AS0125.
Label syntax
The following example shows the label syntax for the Caption property:
Caption = 'Developer translation for %1', Comment = '%1 is extension name', Locked = false, MaxLength = 999;
Note
The Comment, Locked, and MaxLength attributes are optional, and the order isn't enforced. Learn more in Label data type.
Use the same syntax for report labels:
labels
{
LabelName = 'Label text', Comment = 'Context for the translator', MaxLength = 999, Locked = true;
}
And the following is the syntax for Label data types:
var
GreetingLabel: Label 'Label text', Comment = 'Context for the translator', MaxLength = 999, Locked = true;
The XLIFF file
In the generated .xlf file, you can see a <source> element for each label. For the translation, you need to add the target-language and a <target> element per label. Specify the target-language in the format "<language code>-<country code>", such as "da-DK", "es-ES", or "de-DE". The <trans-unit id> attribute identifies the object or object member that defines the text. Its format depends on whether you enable namespace-aware translation IDs. This format is illustrated in the following example.
The following example uses the legacy translation ID format.
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="da-DK" original="ALProject16">
<body>
<group id="body">
<trans-unit id="PageExtension 1716690578 - Property 2879900210" maxWidth="999" size-unit="char" translate="yes" xml:space="preserve">
<source>Developer translation for %1</source>
<target>Udvikleroversættelse for %1</target>
<note from="Developer" annotates="general" priority="2">%1 is extension name</note>
<note from="Xliff Generator" annotates="general" priority="3">PageExtension - PageExtension</note>
</trans-unit>
</group>
</body>
</file>
</xliff>
Note
You can have only one .xlf file per language. If you translate your extension to multiple languages, you must have a translation file per language. There is no enforced naming on the file, but it's a good practice to name it <extensionname>.<language>.xlf.
When the extension is built and published, you can change the language of Dynamics 365 Business Central to view the UI in the translated language.
Translating other extensions
To translate other extensions, for example, when adding translations to the Base Application, you must reference the project to be translated using the dependencies section in the app.json file. For more information, see JSON Files. When the dependencies are set, you can add xliff files in your current project that translates the object captions of the referenced extension. Create a directory named Translations, in the root of the extension, and place the translated xliff file there. When your extension is then built and published, change the language of Dynamics 365 Business Central to view the UI in the translated language.
Note
When translating other extensions, make sure that the attribute original in the <file> element in the xliff file is not set to the name of the current app. Otherwise, translations are only used to translate labels in the same app.
For apps where translations are meant to translate the current app, the generated xliff file will have the correct value of the app name.
Use the <trans-unit id> of the label where it was defined
In order to translate other apps, you must use the <trans-unit id> of the original property, not the one of an extension object as that might have been modified.
The following examples use the legacy translation ID format.
If MyPage is defined as:
page 50000 MyPage
{
Caption = 'Base Page';
}
and it has <trans-unit id> for the page corresponding to Page 2931038265 - Property 2879900210.
And if the following page extension of MyPage called MyPageExtension:
pageextension 50000 MyPageExtension extends MyPage
{
Caption = 'Extension Page';
}
has <trans-unit id> for the page extension corresponding to PageExtension 1716690578 - Property 2879900210, then if you want to change the caption on the page, you must use the ID Page 2931038265 - Property 2879900210, which is the <trans-unit id> of the original property.
Related information
Working with labels
Working with multiple AL project folders within one workspace
JSON Files
Translate user interface files using the Dynamics 365 Translation Service