Skip to main content
Sonamu provides helper functions to assist with writing multilingual messages.

josa - Korean Particle Handling

The josa() function selects the appropriate Korean particle based on whether the preceding word ends with a consonant (batchim):
import { josa } from "sonamu/dict";

josa("μ‚¬λžŒ", "μ€λŠ”"); // "μ‚¬λžŒμ€"
josa("λ‚˜", "μ€λŠ”"); // "λ‚˜λŠ”"

josa("λ¬Ό", "이가"); // "물이"
josa("λ°”λ‹€", "이가"); // "λ°”λ‹€κ°€"

josa("λ°₯", "을λ₯Ό"); // "λ°₯을"
josa("컀피", "을λ₯Ό"); // "컀피λ₯Ό"

josa("λΉ΅", "과와"); // "λΉ΅κ³Ό"
josa("우유", "과와"); // "μš°μœ μ™€"

josa("μ§‘", "으둜"); // "μ§‘μœΌλ‘œ"
josa("학ꡐ", "으둜"); // "ν•™κ΅λ‘œ"

Supported Particles

ParticleWith final consonantWithout final consonant
μ€λŠ”μ€λŠ”
이가이가
을λ₯Όμ„λ₯Ό
과와과와
으둜으둜둜

Using in Dictionary

// ko.ts
import { josa } from "sonamu/dict";

export default {
  "validation.required": (field: string) => `${josa(field, "μ€λŠ”")} ν•„μˆ˜μž…λ‹ˆλ‹€`,
  "validation.duplicate": (field: string) => `이미 μ‚¬μš©μ€‘μΈ ${josa(field, "이가")} μžˆμŠ΅λ‹ˆλ‹€`,
  "error.notFound": (name: string) => `${josa(name, "을λ₯Ό")} 찾을 수 μ—†μŠ΅λ‹ˆλ‹€`,
} as const;

// Usage
SD("validation.required")("이메일"); // "이메일은 ν•„μˆ˜μž…λ‹ˆλ‹€"
SD("validation.required")("이름"); // "이름은 ν•„μˆ˜μž…λ‹ˆλ‹€"

plural - Pluralization Handling

The plural() function returns different text based on the number:
import { plural } from "sonamu/dict";

plural(0, { zero: "none", one: "1 item", other: "multiple items" }); // "none"
plural(1, { zero: "none", one: "1 item", other: "multiple items" }); // "1 item"
plural(5, { zero: "none", one: "1 item", other: "multiple items" }); // "multiple items"

// Using a function for other
plural(5, { other: (n) => `${n} items` }); // "5 items"

// Falls back to other if zero or one is not defined
plural(0, { other: "default" }); // "default"
plural(1, { other: "default" }); // "default"

Options

OptionConditionDescription
zeron === 0Text when count is 0
onen === 1Text when count is 1
otherotherwiseDefault text (required)

Using in Dictionary

// ko.ts
import { plural } from "sonamu/dict";

export default {
  "items.count": (count: number) =>
    plural(count, {
      zero: "ν•­λͺ©μ΄ μ—†μŠ΅λ‹ˆλ‹€",
      one: "1개 ν•­λͺ©",
      other: (n) => `${n}개 ν•­λͺ©`,
    }),

  "cart.items": (count: number) =>
    plural(count, {
      zero: "μž₯λ°”κ΅¬λ‹ˆκ°€ λΉ„μ–΄μžˆμŠ΅λ‹ˆλ‹€",
      other: (n) => `μž₯λ°”κ΅¬λ‹ˆμ— ${n}개 μƒν’ˆ`,
    }),
} as const;

createFormat - Number/Date Formatting

The createFormat() function creates number and date formatters for a specific locale:
import { createFormat } from "sonamu/dict";

const format = createFormat("ko");

format.number(1234567); // "1,234,567"
format.date(new Date("2024-01-15")); // "2024. 1. 15."

const enFormat = createFormat("en");
enFormat.number(1234567); // "1,234,567"
enFormat.date(new Date("2024-01-15")); // "1/15/2024"

Using in Dictionary

// ko.ts
import { createFormat } from "sonamu/dict";

const format = createFormat("ko");

export default {
  "price.display": (price: number) => `${format.number(price)}원`,
  "date.created": (date: Date) => `${format.date(date)} 등둝`,
  "validation.range": (field: string, min: number, max: number) =>
    `${field}은(λŠ”) ${format.number(min)}~${format.number(max)} 사이여야 ν•©λ‹ˆλ‹€`,
} as const;

Combining Multiple Helpers

Complex messages can be written by combining multiple helpers:
// ko.ts
import { createFormat, josa, plural } from "sonamu/dict";

const format = createFormat("ko");

export default {
  // josa + plural
  "search.results": (keyword: string, count: number) =>
    `'${keyword}'${josa(keyword, "으둜")} κ²€μƒ‰ν•œ κ²°κ³Ό ` +
    plural(count, {
      zero: "μ—†μŒ",
      other: (n) => `${format.number(n)}건`,
    }),

  // format + josa
  "order.total": (itemCount: number, total: number) =>
    `${itemCount}개 μƒν’ˆ, 총 ${format.number(total)}원`,

  // Complex message
  "dashboard.summary": (userName: string, taskCount: number, date: Date) =>
    `${userName}λ‹˜, ${format.date(date)} κΈ°μ€€ ` +
    plural(taskCount, {
      zero: "μ²˜λ¦¬ν•  μž‘μ—…μ΄ μ—†μŠ΅λ‹ˆλ‹€",
      one: "1개의 μž‘μ—…μ΄ λŒ€κΈ° μ€‘μž…λ‹ˆλ‹€",
      other: (n) => `${n}개의 μž‘μ—…μ΄ λŒ€κΈ° μ€‘μž…λ‹ˆλ‹€`,
    }),
} as const;

Using the SD Function

Writing and using dictionaries

Localized Columns

Multilingual DB column support