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 koname_ko β name β name_enenname_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 namename_ko, name_enName titletitle_ko, title_enTitle descriptiondescription_ko, description_enDescription contentcontent_ko, content_enContent
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.
i18n Setup Initial i18n configuration
Using the SD Function Writing and using dictionaries