Search

    Localization (i18n)

    Guides you through the steps to internationalize your application to provide localized versions with respect to both Localized Models as well as Localized Data.

    With ‘Localization’, we refer to adapting your app to the languages of specific target markets. This is needed when serving UIs.

    This guide focuses on static texts like labels. See CDS also Localized Data on how to manage and serve actual payload data in different translation.

    Content

    Externalizing Texts Bundles

    All you have to do to internationalize your models is to externalize all your literal texts to text bundles and refer to the respective keys from your models as annotation values. Here is a sample of a model and the corresponding bundle.

    srv/my-service.1.cds

    service Bookshop {
      entity Books @(
        UI.HeaderInfo: {
          Title.Label: '{i18n>Book}',
          TypeName: '{i18n>Book}',
          TypeNamePlural: '{i18n>Books}',
        },
      ){/*...*/}
    }
    

    _i18n/i18n.properties

    Book = Book
    Books = Books
    foo = Foo
    

    The keys of your properties entries can be freely chosen.

    Learn more about annotations in CSN.

    Then you can translate the texts in localized bundles each with a language/locale code appended to its name, for example,

    _i18n/
      i18n.properties           # dev main --› 'default fallback'
      i18n_en.properties        # English    --› 'default language'
      i18n_de.properties        # German
      i18n_zh_TW.properties     # Traditional Chinese
      ...
    

    Where to Place Text Bundles?

    By default, text bundles can be placed in and are fetched from folders named _ i18n, i18n, or assets/i18n. These folders are placed next to the model files or in a parent folder as follows:

    srv/
       my-service.cds          # the model file
       _i18n/i18n.properties   # next to the model file
    _i18n/i18n.properties      # in a parent folder
    

    You can configure the folder names where cds searches for property bundles by setting cds.i18n.folders in your project’s package.json.

    The default is:

    "cds":{"i18n":{
      "folders": [ "_i18n", "i18n", " assets/i18n" ]
    }}
    

    These folders are resolved relative to the working directory of the application.

    CSV-Based Text Bundles

    For smaller projects you may choose CSV files instead of .properties files, which you can easily edit in Excel, Numbers or alike.

    The format is like that:

    key en de zh_CN
    Book Book Buch  
    Books Books Bücher  
           

    With that CSV source:

    key;en;de;zh_CN;...
    Book;Book;Buch;...
    Books;Books;Bücher;...
    ...
    

    Merging Algorithm

    Each localized model is constructed by applying:

    1. The default fallback bundle (that is, i18n.properties), then …
    2. The default language bundle (usually i18n_en.properties), then …
    3. The requested bundle (for example, i18n_de.properties), in that order.

    So, the complete stack of overlaid models for the given example would look like that (higher ones override lower ones):

    Source Content
    _ i18n/i18n_de.properties specific language bundle
    _ i18n/i18n_en.properties default language bundle
    _ i18n/i18n.properties default fallback bundle
    srv/my-service.cds service definition
    db/data-model.cds underlying data model

    Note
    The default language is usually en but can be overridden by configuring cds.i18n.default_language in your project’s package.json.

    Merging Reuse Bundles

    In case your application is importing models from a reuse package, that package comes with own language bundles for localization. These are applied upon import, so can be overridden in your models as well as in your language bundles and translations thereof.

    For example, assumed your data model imports from a foundation package, then the overall stack of overlays would look like that:

    Source
    ./_i18n/i18n_de.properties
    ./_i18n/i18n_en.properties
    ./_i18n/i18n.properties
    ./srv/my-service.cds
    ./db/data-model.cds
    foundation/_i18n/i18n_de.properties
    foundation/_i18n/i18n_en.properties
    foundation/_i18n/i18n.properties
    foundation/index.cds
    _foundation/.cds_
    _foundation/.cds_

    Determining User Locales

    Upon incoming requests at runtime, the user’s preferred language is determined as follows:

    1. Read the preferred language from first of:
      1. The value of URL parameter sap-language, if present
      2. A chosen language from the user’s applications settings, if available
      3. A chosen language in the user’s global settings, if available
      4. The first entry from the request’s Accept-Language header
      5. The default language configured on app level (for example, en)
    2. Narrow to normalized locales as described below.

    CAP does accept formats following the available standards of POSIX and RFC 1766 and transforms into normalized locales.

    Normalized Locales

    To reduce the number of required translations, determined locales are normalized as follows:

    • Most locales are narrowed to their main language codes only
    • For example, en_US, en_CA, en_AUen
    • Except of these allowed ones:
    Locale Language
    zh_CN Chinese - China
    zh_HK Chinese - Hong Kong, China
    zh_TW Chinese traditional - Taiwan, China
    en_GB English - English
    fr_CA French - Canada
    pt_PT Portuguese - Portugal
    es_CO Spanish - Colombia
    es_MX Spanish - Mexico
    en_US_x_saptrc SAP tracing translations w/ sap-language=1Q
    en_US_x_sappsd SAP pseudo translations w/ sap-language=2Q

    Due to the ambiguity with regards to standards, for example, the usage of hyphen (-) in contrast to underscore (_), CAP followed the approach of the SAP Translation Hub. That approach includes, that CAP normalizes locales to underscore as our de facto standard.

    Show/Hide Beta Features