> ## Documentation Index
> Fetch the complete documentation index at: https://sonamu.cartanova.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SD Function and Dictionary

> Using the type-safe translation function

## Basic Usage of SD Function

The `SD` (Sonamu Dictionary) function returns translated text matching the current Context's locale:

```typescript theme={null}
import { SD } from "../i18n/sd.generated";

// Simple string
const saveButton = SD("common.save"); // "저장" (ko) / "Save" (en)

// Function value (dynamic message)
const message = SD("common.results")(42); // "42개 결과"
const error = SD("notFound")("User", 123); // "존재하지 않는 User ID 123"
```

## Type Safety

Using a non-existent key results in a compile-time error:

```typescript theme={null}
SD("common.save"); // ✅ OK
SD("common.savee"); // ❌ Compile error: key 'common.savee' does not exist
SD("typo.key"); // ❌ Compile error
```

## Forcing a Specific Locale

Use `SD.locale()` to get values for a specific locale regardless of Context:

```typescript theme={null}
const EN = SD.locale("en");
const KO = SD.locale("ko");

EN("common.save"); // "Save" (always English)
KO("common.save"); // "저장" (always Korean)

// Switch to recipient's locale when sending emails
async function sendEmail(userLocale: string, email: string) {
  const L = SD.locale(userLocale);
  await mailer.send({
    to: email,
    subject: L("email.welcome.subject"),
    body: L("email.welcome.body"),
  });
}
```

## Getting Enum Labels

`SD.enumLabels()` returns a Proxy with labels for all values of an Enum:

```typescript theme={null}
// Enum defined in Entity
// enumLabels: { UserRole: { admin: "관리자", normal: "일반" } }

const labels = SD.enumLabels("UserRole");
labels["admin"]   // "관리자"
labels["normal"]  // "일반"

// Using in Select component
<Select
  options={Object.entries(UserRole).map(([key, value]) => ({
    value,
    label: SD.enumLabels("UserRole")[value],
  }))}
/>
```

## Dictionary Writing Patterns

### Key Naming Conventions

```typescript theme={null}
export default {
  // domain.action or domain.item
  "common.save": "저장",
  "common.cancel": "취소",

  // Error messages
  "error.notFound": "찾을 수 없습니다",
  "error.unauthorized": "인증이 필요합니다",

  // Validation messages
  "validation.required": (field: string) => `${field}은(는) 필수입니다`,
  "validation.email": "올바른 이메일 형식이 아닙니다",

  // Page/feature specific
  "login.title": "로그인",
  "login.submit": "로그인",
  "dashboard.welcome": "환영합니다!",

  // Confirmation messages
  "confirm.delete": "정말 삭제하시겠습니까?",
} as const;
```

### Writing Function Values

Use arrow functions when dynamic values are needed:

```typescript theme={null}
export default {
  // Simple interpolation
  "common.results": (count: number) => `${count}개 결과`,

  // Multiple parameters
  "entity.edit": (name: string, id: number) => `${name} 수정 (#${id})`,

  // Conditional text
  "items.count": (count: number) => (count === 0 ? "항목 없음" : `${count}개 항목`),

  // Using helper functions
  "validation.required": (field: string) => `${josa(field, "은는")} 필수입니다`,
  "validation.range": (field: string, min: number, max: number) =>
    `${field}은(는) ${format.number(min)}~${format.number(max)} 사이여야 합니다`,
} as const;
```

## Using in Models

```typescript theme={null}
import { SD } from "../i18n/sd.generated";

class UserModelClass extends BaseModelClass {
  @api({ httpMethod: "GET" })
  async findById<T extends UserSubsetKey>(subset: T, id: number) {
    const { rows } = await this.findMany(subset, { id, num: 1, page: 1 });
    if (!rows[0]) {
      // i18n error message
      throw new NotFoundException(SD("notFound")("User", id));
    }
    return rows[0];
  }

  @api({ httpMethod: "POST" })
  async register(params: UserRegisterParams) {
    const existing = await this.findOne("A", { email: params.email });
    if (existing) {
      throw new BadRequestException(SD("user.email.duplicate"));
    }
    // ...
  }
}
```

<CardGroup cols={2}>
  <Card title="Helper Functions" icon="wand-magic-sparkles" href="/en/advanced-features/i18n/helpers">
    Using josa, plural, format
  </Card>

  <Card title="Entity Labels" icon="tag" href="/en/advanced-features/i18n/entity-labels">
    Auto-extracted labels
  </Card>
</CardGroup>
