SuperAPI AI Directory

localization

General & other

View repository

Updated 10-16 02:37

About this skill

Localization — CAP Best Practices

Primary reference: https://cap.cloud.sap/docs/guides/i18n
Localized data: https://cap.cloud.sap/docs/guides/localized-data

Localized entity elements

Mark translatable fields with localized:

entity Products : cuid {
  localized title       : String(111);
  localized description : LargeString;
  price                 : Decimal(9,2);  // not localized — price is not translated
  currency              : Currency;
}

CAP auto-generates a Products_texts table with locale and ID keys. Translations are served automatically based on req.locale.

CSV for seed data (correct format since Nov 2025 docs update)

// db/data/my.namespace-Products.csv  (comma-separated, not semicolons!)
ID,title,descr,price,currency_code
d4f1c8b2-...,Laptop,High performance laptop,999.99,EUR

// db/data/my.namespace-Products_texts.csv
ID,locale,title,descr
d4f1c8b2-...,de,Laptop,Hochleistungs-Laptop
d4f1c8b2-...,fr,Laptop,Ordinateur portable haute performance

Note: CAP documentation updated Nov 2025 — use comma-separated CSV, not semicolons.

i18n message bundles

Structure:

_i18n/
  i18n.properties         ← default (English)
  i18n_de.properties      ← German
  i18n_fr.properties      ← French
  i18n_ja.properties      ← Japanese

_i18n/i18n.properties:

# UI labels
Products=Products
Title=Title
Description=Description
Price=Price

# Error messages (with positional placeholders)
PRODUCT_NOT_FOUND=Product {0} was not found
INSUFFICIENT_STOCK=Insufficient stock: requested {0}, available {1}
ORDER_ALREADY_CLOSED=Order {0} is already closed and cannot be modified

_i18n/i18n_de.properties:

Products=Produkte
Title=Titel
Description=Beschreibung
PRODUCT_NOT_FOUND=Produkt {0} wurde nicht gefunden
INSUFFICIENT_STOCK=Nicht genügend Lagerbestand: angefordert {0}, verfügbar {1}

Using i18n keys in annotations

annotate Products with @(
  title : '{i18n>Products}',
  UI.LineItem : [
    { Value: title,  Label: '{i18n>Title}' },
    { Value: price,  Label: '{i18n>Price}' },
  ]
);

Using i18n keys in handlers (error messages)

// CAP resolves the key using req.locale automatically
req.reject(404, 'PRODUCT_NOT_FOUND', [productId])
req.reject(422, 'INSUFFICIENT_STOCK', [requested, available])
req.warn(200, 'ORDER_ALREADY_CLOSED', [orderId])

Currency, Country, Language reuse types

using { Currency, Country, Language } from '@sap/cds/common';

entity Products : cuid {
  price    : Decimal(9,2);
  currency : Currency;       // Association to sap.common.Currencies
  origin   : Country;        // Association to sap.common.Countries
}

Seed pre-built content (currencies, countries, languages):

npm install @sap/cds-common-content --save-dev
// package.json
{
  "cds": {
    "requires": {
      "db": {
        "model": ["@sap/cds-common-content", "db", "srv"]
      }
    }
  }
}

Locale-aware querying

// req.locale is set from Accept-Language header automatically
async onReadProducts(req) {
  const { locale } = req  // e.g. 'de', 'en', 'ja'

  // CAP serves localized data automatically for localized elements
  // No extra code needed — just read normally:
  return SELECT.from(Products)
}

Manual locale override (rare):

const products = await SELECT.from(Products).where('...').localized(req.locale)

Temporal data (time-variant localization)

using { temporal } from '@sap/cds/common';

entity PriceHistory : cuid, temporal {
  product  : Association to Products;
  price    : Decimal(9,2);
  currency : Currency;
}

temporal adds validFrom / validTo. CAP filters to the current period automatically.

Common mistakes to avoid

  • ❌ Using semicolons in CSV data files — use commas (capire docs corrected this Nov 2025)
  • ❌ Hardcoding translated strings in service handlers — always use _i18n/ keys
  • ❌ Defining Currency/Country as plain String(3) — use the reuse types for value help & OData interop
  • ❌ Forgetting _texts CSV files — entity data loads but no translations show
  • ❌ Using @title: 'Products' (hardcoded) instead of @title: '{i18n>Products}' (translatable)
  • ❌ Not adding the @sap/cds-common-content model to cds.requires.db.model — currencies/countries empty