When you need to store multilingual values in the database, you can use locale-specific columns like name, name_ko, name_en. Sonamu automatically selects the appropriate value for the current locale using the localizedColumn() function.
localizedColumn Function
import { localizedColumn } from "../i18n/sd.generated";
const tag = {
id: 1,
name: "default",
name_ko: "태그",
name_en: "Tag",
};
// When Context locale is "ko"
localizedColumn(tag, "name") // "태그"
// When Context locale is "en"
localizedColumn(tag, "name") // "Tag"
// When Context locale is "ja" (unsupported locale)
localizedColumn(tag, "name") // "default" (falls back to base column)
Priority Order
localizedColumn() looks for values in the following order:
| Current locale | Priority |
|---|
ko | name_ko → name → name_en |
en | name_en → name → name_ko |
Empty strings ("") and null are skipped, and the next priority is checked.
Entity Definition
Example of an Entity with multilingual columns:
{
"id": "Tag",
"table": "tags",
"props": [
{ "name": "id", "type": "integer" },
{ "name": "name", "type": "string", "length": 100, "desc": "Default name" },
{ "name": "name_ko", "type": "string", "length": 100, "nullable": true, "desc": "Korean name" },
{ "name": "name_en", "type": "string", "length": 100, "nullable": true, "desc": "English name" }
]
}
Using in Models
Processing in Subset
You can use localizedColumn in a Subset’s enhancer to deliver only a single name field to the client:
import { localizedColumn } from "../i18n/sd.generated";
class TagModelClass extends BaseModelClass {
async findMany<T extends TagSubsetKey>(subset: T, params: TagListParams) {
// ...
const enhancers = this.createEnhancers({
A: (row) => ({
...row,
// Replace with locale-appropriate name
displayName: localizedColumn(row, "name"),
}),
});
return this.executeSubsetQuery({ subset, qb, params, enhancers });
}
}
Using in API Response
@api({ httpMethod: "GET" })
async getTagOptions(): Promise<{ id: number; label: string }[]> {
const tags = await this.findMany("A", { num: 100 });
return tags.rows.map(tag => ({
id: tag.id,
label: localizedColumn(tag, "name") ?? tag.name,
}));
}
Using in Frontend
The same function can be used in the frontend (exported from web’s sd.generated.ts):
import { localizedColumn } from "@/i18n/sd.generated";
function TagBadge({ tag }: { tag: Tag }) {
return (
<span className="badge">
{localizedColumn(tag, "name")}
</span>
);
}
Column Naming Patterns
| Base column | Locale columns | Description |
|---|
name | name_ko, name_en | Name |
title | title_ko, title_en | Title |
description | description_ko, description_en | Description |
content | content_ko, content_en | Content |
Column names must follow the {base_column}_{locale} format. Example: name_ko, title_en
Important Notes
localizedColumn is simply a function that selects column values. Query optimization (SELECTing only necessary columns) must be handled separately.
- If all locale columns are
null and the base column is also empty, undefined is returned.
- If locale is not set in Context,
defaultLocale is used.