Localization

Localization adapts your application to linguistic and regional differences. DevExtreme allows you to localize:

DevExtreme also supports right-to-left layout.

NOTE
Refer to the Using Intl and Using Globalize articles if you are localizing DevExtreme ASP.NET MVC Control.

Dictionaries

Dictionaries are files that contain localized strings for different languages. These are JavaScript or JSON files depending on the packaging you use. DevExpress curates the following dictionaries:

  • English (en) (default)
  • German (de)
  • Japanese (ja)
  • Russian (ru)

The community contributed and is curating the following dictionaries:

  • Czech (cs)
  • Chinese (zh)
  • Finnish (fi)
  • French (fr)
  • Italian (it)
  • Brazilian Portuguese (pt)
  • Spanish (es)
  • Swedish (sv)

You can find all the dictionaries on your local machine in the DevExtreme installation folder's or ZIP archive's Lib\js\localization directory. These dictionaries are also available on CDN and npm. See the topics on localization libraries for code examples and details on using them.

NOTE
Dictionaries can be used without localization libraries. However, you need a localization library to localize numbers, dates, and currencies.

To make a custom dictionary:

  1. Copy one of the available dictionaries.
  2. Rename it according to a new locale.
  3. Translate the strings in it.
  4. Link it to your page using a <script> tag.

You can submit custom dictionaries to our repository on GitHub. Please, refer to our Contribution Guide before submitting content.

Create a New Dictionary

To make a dictionary for a new locale:

  1. Copy one of the available dictionaries.
  2. Rename it according to the new locale.
  3. Translate the strings in it and change the locale key.

You can submit JSON dictionaries to our repository on GitHub. You should refer to our Contribution Guide before submitting content.

Localize Dates, Numbers, and Currencies

DevExtreme enables you to localize date, number and currency values using Intl or Globalize. We recommend using Intl because it is easy to activate. You can use Globalize instead if the target browser or its polyfills do not support Intl, or if your app is already using Globalize.

Using Intl

Intl is the short name used to refer to a particular ECMAScript Internationalization API object. DevExtreme supports this API via the DevExtreme-Intl module. It is available on CDN and npm, or you can save the module (JavaScript file) on your local machine.

  • CDN or local file

    Use the <script> tag as shown in the example below to include the DevExtreme-Intl module. German and Russian dictionaries are included in this example. You can also add or replace dictionaries.

    CDN
    HTML
    <head>
        <!-- ... -->
        <!-- DevExtreme library -->
        <script src="https://cdn3.devexpress.com/jslib/18.2.3/js/dx.all.js"></script>
        <!-- DevExtreme-Intl module -->
        <script src="https://unpkg.com/devextreme-intl@18.2/dist/devextreme-intl.min.js"></script>
        <!-- Dictionary files for German and Russian languages -->
        <script src="https://cdn3.devexpress.com/jslib/18.2.3/js/localization/dx.messages.de.js"></script>
        <script src="https://cdn3.devexpress.com/jslib/18.2.3/js/localization/dx.messages.ru.js"></script>
    </head>
    <body>
        <script>
            DevExpress.localization.locale(navigator.language || navigator.browserLanguage);
            // ...
            // DevExtreme widgets are configured here
            // ...
        </script>
    </body>

    View Demo

  • npm

    Install the devextreme-intl package:

    npm install --save-dev devextreme-intl

    Then, include the devextreme-intl module using the import or require statement—the statement depends on the syntax for working with modules. The code below shows ECMAScript 6 and CommonJS syntaxes. These examples include German and Russian dictionaries.

    npm: ECMAScript 6 syntax
    JavaScript
    // ...
    import "devextreme-intl";
    // Dictionaries for German and Russian languages
    import deMessages from "devextreme/localization/messages/de.json!json";
    import ruMessages from "devextreme/localization/messages/ru.json!json";
    import { locale, loadMessages } from "devextreme/localization";
    
    loadMessages(deMessages);
    loadMessages(ruMessages);
    locale(navigator.language || navigator.browserLanguage)
    npm: CommonJS syntax
    JavaScript
    // ...
    require("devextreme-intl");
    // Dictionaries for German and Russian languages
    const deMessages = require('devextreme/localization/messages/de.json');
    const ruMessages = require('devextreme/localization/messages/ru.json');
    const localization = require('devextreme/localization');
    
    localization.loadMessages(deMessages);
    localization.loadMessages(ruMessages);
    localization.locale(navigator.language || navigator.browserLanguage);

    View Demo

The Intl setup automatically localizes and formats string, number, date, and currency values according to the specified locale. You can use a currency other than USD globally or in format definitions:

jQuery
JavaScript
$(function() {
    // Specifying a currency globally
    DevExpress.config({ defaultCurrency: "EUR" });

    $("#dataGridContainer").dxDataGrid({
        // ...
        columns: [{
            dataField: "Price",
            // Specifying a currency in a format definition
            format: {
                type: "currency",
                currency: "RUB"
            }
        }]
    });
});
Angular
TypeScript
HTML
import config from "devextreme/core/config";
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    constructor() {
        // Specifying a currency globally
        config({ defaultCurrency: "EUR" });      
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
<dx-data-grid ... >
    <dxi-column dataField="price">
        <!-- Specifying a currency in a format definition -->
        <dxo-format
            type="currency"
            currency="RUB">
        </dxo-format>
    </dxi-column>
</dx-data-grid>

You can use structures compatible with the Intl API for value formatting. See an example in the DevExtreme-Intl README's API section. The Value Formatting article provides information on the extended formatting functionality DevExtreme provides out of the box.

You can use the Intl-Angular sample project as a starting point for creating new apps or as an example to copy code from when implementing specific functionality in your app.

Using Globalize

Activating Globalize in your project requires the following files:

  • Globalize library
  • CLDR library
  • CLDR JSON files for each required language.

You can find the Globalize and CLDR libraries on your local machine in the DevExtreme installation folder's or ZIP archive's Lib\js directory.

CLDR JSON files are available in the Unicode-CLDR repository. Refer to this table for details on which CLDR JSONs you may require.

All the components are also available via CDN and npm.

  • CDN or local files

    Include the Globalize and CLDR libraries along with the dictionaries using <script> tags as shown below. The order is important. Then, load CLDR JSONs using $.getJSON calls (you need to add the jQuery script) and set the locale using the Globalize.locale() method:

    CDN
    HTML
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <!-- ... -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/cldrjs/0.5.0/cldr.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/cldrjs/0.5.0/cldr/event.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/cldrjs/0.5.0/cldr/supplemental.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.3.0/globalize.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.3.0/globalize/message.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.3.0/globalize/number.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.3.0/globalize/currency.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.3.0/globalize/date.min.js"></script>
        <!-- DevExtreme library -->
        <script src="https://cdn3.devexpress.com/jslib/18.2.3/js/dx.all.js"></script>
        <!-- Dictionary files for German and Russian languages -->
        <script src="https://cdn3.devexpress.com/jslib/18.2.3/js/localization/dx.messages.de.js"></script>
        <script src="https://cdn3.devexpress.com/jslib/18.2.3/js/localization/dx.messages.ru.js"></script>
    </head>
    <script>
        $(function() {
            $.when(
                // Gets language-specific CLDR JSONs for German and Russian
                $.getJSON("https://unpkg.com/cldr-dates-full/main/de/ca-gregorian.json"),
                $.getJSON("https://unpkg.com/cldr-numbers-full/main/de/numbers.json"),
                $.getJSON("https://unpkg.com/cldr-numbers-full/main/de/currencies.json"),
                $.getJSON("https://unpkg.com/cldr-dates-full/main/ru/ca-gregorian.json"),
                $.getJSON("https://unpkg.com/cldr-numbers-full/main/ru/numbers.json"),
                $.getJSON("https://unpkg.com/cldr-numbers-full/main/ru/currencies.json"),
                $.getJSON("https://unpkg.com/cldr-core/supplemental/likelySubtags.json"),
                $.getJSON("https://unpkg.com/cldr-core/supplemental/timeData.json"),
                $.getJSON("https://unpkg.com/cldr-core/supplemental/weekData.json"),
                $.getJSON("https://unpkg.com/cldr-core/supplemental/currencyData.json"),
                $.getJSON("https://unpkg.com/cldr-core/supplemental/numberingSystems.json")
            ).then(function () {
                // Normalizes $.getJSON results getting only the JSON without the request statuses
                return [].slice.apply( arguments, [0] ).map(function( result ) {
                    return result[0];
                });
            }).then( Globalize.load ).then(function() {
                Globalize.locale(navigator.language || navigator.browserLanguage);
            });
        });
    </script>

    View Demo

  • npm

    Install the cldr-data and globalize packages:

    npm install --save-dev cldr-data globalize

    Then, include Globalize, CLDR, CLDR JSONs, and the dictionaries using the import or require statement—the statement depends on the syntax for working with modules. The following code shows ECMAScript 6 syntax used with a SystemJS module loader, and CommonJS syntax used with a Webpack module bundler:

    npm: ECMAScript 6 syntax / SystemJS configuration
    JavaScript
    import "devextreme/localization/globalize/number";
    import "devextreme/localization/globalize/date";
    import "devextreme/localization/globalize/currency";
    import "devextreme/localization/globalize/message";
    
    // Dictionaries for German and Russian languages
    import deMessages from "devextreme/localization/messages/de.json!json";
    import ruMessages from "devextreme/localization/messages/ru.json!json";
    
    // Language-specific CLDR JSONs for German and Russian
    import deCaGregorian from "cldr-data/main/de/ca-gregorian.json!json";
    import deNumbers from "cldr-data/main/de/numbers.json!json";
    import deCurrencies from "cldr-data/main/de/currencies.json!json";
    import ruCaGregorian from "cldr-data/main/ru/ca-gregorian.json!json";
    import ruNumbers from "cldr-data/main/ru/numbers.json!json";
    import ruCurrencies from "cldr-data/main/ru/currencies.json!json";
    
    import likelySubtags from "cldr-data/supplemental/likelySubtags.json!json";
    import timeData from "cldr-data/supplemental/timeData.json!json";
    import weekData from "cldr-data/supplemental/weekData.json!json";
    import currencyData from "cldr-data/supplemental/currencyData.json!json";
    import numberingSystems from "cldr-data/supplemental/numberingSystems.json!json";
    
    import Globalize from "globalize";
    
    Globalize.load(
        deCaGregorian, deNumbers, deCurrencies,
        ruCaGregorian, ruNumbers, ruCurrencies,
        likelySubtags,
        timeData,
        weekData,
        currencyData,
        numberingSystems
    );
    
    Globalize.loadMessages(deMessages);
    Globalize.loadMessages(ruMessages);
    
    Globalize.locale(navigator.language || navigator.browserLanguage)

    config.js

    JavaScript
    System.config({
        // ...
        paths: {
            "npm:": "node_modules/"
        },
        map: {
            // ...
            "globalize": "npm:globalize/dist/globalize",
            "cldr": "npm:cldrjs/dist/cldr",
            "cldr-data": "npm:cldr-data",
            "json": "npm:systemjs-plugin-json/json.js",
        },
        packages: {
            app: {
                // ...
                "globalize": {
                    main: "../globalize.js",
                    defaultExtension: "js"
                },
                "cldr": {
                    main: "../cldr.js",
                    defaultExtension: "js"
                }
            }
        }
    });
    npm: CommonJS syntax / Webpack configuration
    JavaScript
    require("devextreme/localization/globalize/message");
    require("devextreme/localization/globalize/number");
    require("devextreme/localization/globalize/currency");
    require("devextreme/localization/globalize/date");
    
    // Dictionaries for German and Russian languages
    const deMessages = require("devextreme/localization/messages/de.json");
    const ruMessages = require("devextreme/localization/messages/ru.json");
    
    const Globalize = require("globalize");
    Globalize.load(
        // Language-specific CLDR JSONs for German and Russian
        require("cldr-data/main/de/ca-gregorian.json"),
        require("cldr-data/main/de/numbers.json"),
        require("cldr-data/main/de/currencies.json"),
        require("cldr-data/main/ru/ca-gregorian.json"),
        require("cldr-data/main/ru/numbers.json"),
        require("cldr-data/main/ru/currencies.json"),
        require("cldr-data/supplemental/likelySubtags.json"),
        require("cldr-data/supplemental/timeData.json"),
        require("cldr-data/supplemental/weekData.json"),
        require("cldr-data/supplemental/currencyData.json"),
        require("cldr-data/supplemental/numberingSystems.json")
    );
    
    Globalize.loadMessages(deMessages);
    Globalize.loadMessages(ruMessages);
    
    Globalize.locale(navigator.language || navigator.browserLanguage);

    webpack.config.js

    JavaScript
    module.exports = {
        // ...
        resolve: {
            alias: {
                globalize$: path.resolve( __dirname, "node_modules/globalize/dist/globalize.js" ),
                globalize: path.resolve(__dirname, "node_modules/globalize/dist/globalize"),
                cldr$: path.resolve(__dirname, "node_modules/cldrjs/dist/cldr.js"),
                cldr: path.resolve(__dirname, "node_modules/cldrjs/dist/cldr")
            }
        }
    }

    View Demo

Strings, numbers, dates, and currencies are now automatically localized and formatted according to the specified locale. You can also use a currency other than USD (see the last example in the Using Intl topic).

In addition, you can now format values using structures accepted by numberFormatter, currencyFormatter, and dateFormatter, for example:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        columns: [{
            dataField: "OrderDate",
            format: { skeleton: "yMMMd" }
        }, {
            dataField: "SaleAmount",
            format: { currency: "EUR", maximumFractionDigits: 2 }
        }]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column
        dataField="OrderDate"
        [format]="{ skeleton: 'yMMMd' }">
    </dxi-column>
    <dxi-column
        dataField="SaleAmount"
        [format]="{ currency: 'EUR', maximumFractionDigits: 2 }">
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
See Also

Localize Custom Values

DevExtreme provides an API for localizing messages, dates, or numbers in your app.

The following example demonstrates how to localize a message. The loadMessages() method loads dictionaries for several locales. The current locale is specified using the locale() method. The formatMessage() method gets a message from the current locale's dictionary.

jQuery
JavaScript
HTML
$(function() {
    var userName = "John";
    DevExpress.localization.loadMessages({
        "en": {
            "greetingMessage": "Good morning, {0}!"
        },
        "de": {
            "greetingMessage": "Guten morgen, {0}!"
        }
    })
    DevExpress.localization.locale(navigator.language || navigator.browserLanguage);
    $("#greeting").text(
        DevExpress.localization.formatMessage("greetingMessage", userName)
    )
})
<h1 id="greeting"></h1>
Angular
TypeScript
HTML
import { formatMessage, loadMessages, locale } from "devextreme/localization";
// ...
export class AppComponent {
    constructor() {
        loadMessages({
            "en": {
                "greetingMessage": "Good morning, {0}!"
            },
            "de": {
                "greetingMessage": "Guten morgen, {0}!"
            }
        })
        locale(navigator.language || navigator.browserLanguage)
    }
    userName: string = "John";
    get greeting() {
        return formatMessage("greetingMessage", this.userName);
    }
}
<h1>{{greeting}}</h1>

To localize a custom date or number, apply a format to it as shown in the Format Custom Values article. You app should have Intl or Globalize configured.

Right-to-Left Support

Right-to-left (RTL) support allows the widget to adapt its content to right-to-left locales.

RTL layout can be specified for an individual widget using its rtlEnabled option:

jQuery
JavaScript
$(function() {
    $("#sliderContainer").dxSlider({
        // ...
        rtlEnabled: true
    });
});
Angular
HTML
TypeScript
<dx-slider ...
    [rtlEnabled]="true">
</dx-slider>
import { DxSliderModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxSliderModule
    ],
    // ...
})

To apply RTL to your entire application, set the same option globally using the config() function:

jQuery
JavaScript
$(function() {
    DevExpress.config({ rtlEnabled: true });
    // ...
});
Angular
TypeScript
import config from "devextreme/core/config";
// ...
export class AppComponent {
    constructor() {
        config({ rtlEnabled: true });      
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
See Also