Skip to content

Latest commit

 

History

History
180 lines (148 loc) · 3.88 KB

File metadata and controls

180 lines (148 loc) · 3.88 KB

Paraglide Formatting Reference

Official docs:

Generated Messages

Use generated message functions through the app wrapper:

import { m } from "../../i18n/index.js";

m.greeting({ name: "Ada" });

Messages live in frontend/messages/{locale}.json. The English and Simplified Chinese catalogs must have the same keys.

Cardinal Plurals

Use variant messages for counts. Paraglide's plural selector uses Intl.PluralRules, so it works for locales with more than English singular and plural categories.

{
  "tool_call_group_call_count": [
    {
      "declarations": [
        "input count",
        "local countPlural = count: plural"
      ],
      "selectors": ["countPlural"],
      "match": {
        "countPlural=one": "{count} tool call",
        "countPlural=other": "{count} tool calls"
      }
    }
  ]
}

Call with a number:

m.tool_call_group_call_count({ count: 3 });

For zh-CN, use the same declaration and provide the matching locale text; a single other or wildcard branch is often enough only when the locale truly has no visible plural distinction.

Ordinals

Use type=ordinal for values such as 1st, 2nd, and 3rd.

{
  "ranking_place": [
    {
      "declarations": [
        "input place",
        "local placePlural = place: plural type=ordinal"
      ],
      "selectors": ["placePlural"],
      "match": {
        "placePlural=one": "{place}st",
        "placePlural=two": "{place}nd",
        "placePlural=few": "{place}rd",
        "placePlural=*": "{place}th"
      }
    }
  ]
}

Date And Time

For dates inside translatable copy, use the Paraglide datetime formatter in the message declaration so locale formatting and word order stay in the catalog.

{
  "session_started_at": [
    {
      "declarations": [
        "input startedAt",
        "local started = startedAt: datetime dateStyle=medium timeStyle=short"
      ],
      "match": {
        "startedAt=*": "Started {started}"
      }
    }
  ]
}

For standalone visible date/time labels in components, use the app helper:

import { formatDateTime } from "../../i18n/index.js";

formatDateTime(timestamp, {
  month: "short",
  day: "numeric",
  timeZone,
});

Do not hard-code "en" or "en-US" for visible UI formatting. It is acceptable to use a fixed locale for internal sentinel calculations when the formatted string is not displayed.

Relative Dates

Use Paraglide's relativetime formatter. The unit option is required.

{
  "status_bar_synced_ago": [
    {
      "declarations": [
        "input duration",
        "local formattedDuration = duration: relativetime unit=minute numeric=auto"
      ],
      "match": {
        "duration=*": "synced {formattedDuration}"
      }
    }
  ]
}

Use a variable unit only when the caller computes the unit intentionally:

{
  "updated_relative": [
    {
      "declarations": [
        "input duration",
        "input unit",
        "local formattedDuration = duration: relativetime unit=$unit style=short"
      ],
      "match": {
        "duration=*,unit=*": "Updated {formattedDuration}"
      }
    }
  ]
}

Numbers And Currency

Prefer Paraglide's number formatter for numbers embedded in messages:

{
  "usage_total_cost": [
    {
      "declarations": [
        "input amount",
        "local cost = amount: number style=currency currency=USD"
      ],
      "match": {
        "amount=*": "Total cost {cost}"
      }
    }
  ]
}

Use raw toLocaleString() only for non-sentence labels where the browser or app-level locale behavior is already intentional.