Skip to main content
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 localePriority
koname_konamename_en
enname_ennamename_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 columnLocale columnsDescription
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.