i18n String Field

Checks each translation against its source as it is typed, so dropped placeholders, broken tags or missing plural forms don't ship.

StopsTranslation drops a placeholder

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/i18n-string-field.json

The files land in your project. They're yours to edit.

Usage

i18n-string-field-usage.tsx
import { I18nStringField } from "@/components/ui/i18n-string-field"

<I18nStringField
  locale="pl"
  source="{count, plural, one {<b>#</b> file shared with {name}} other {<b>#</b> files shared with {name}}}"
  defaultValue="{count, plural, one {<b>#</b> plik dla {imie}} other {<b>#</b> plików dla {imie}}}"
  rows={3}
/>

What it catches

  • Placeholders dropped or renamed ({count}, %s, %1$s, {{name}})
  • Markup tags missing or left unclosed
  • ICU plural branches the target language needs (via Intl.PluralRules)
  • Translation longer than the UI budget
  • Source text pasted back untranslated

Props

I18nStringField props
PropTypeDefault
source* (required)

The source string, e.g. the English original.

string—
locale* (required)

Target locale (BCP 47), used for plural rules and the label.

string—
sourceLocale

Locale of the source string.

string"en"
maxLength

UI budget in rendered characters (tags don't count, placeholders count as `placeholderLength`).

number—
placeholderLength

Width a placeholder is assumed to render at.

number4
value

Controlled translation.

string—
defaultValue

Initial translation when uncontrolled.

string""
onValueChange

Called with the translation on every change.

(value: string) => void—
label

Visible label. `{language}` is filled in.

string"Translation · {language}"
sourceLabel

Label shown above the source string.

string"Source"
keepSameLabel

Accessible label of the button that accepts a translation identical to the source.

string"It's meant to match the source"

* required. Also accepts the native props of <textarea> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Visible label tied to the field, described by the issues list
  • Issues list is a polite live region
  • Placeholder chips have aria-labels saying present or missing
  • Keep-same button has an aria-label and title

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Plural rules come from the browser's Intl.PluralRules data, which can lag CLDR
  • Rendered length is a character estimate, not measured pixel width
  • Doesn't judge translation quality or meaning

What it stops

Translation drops a placeholder

Also known as

i18n · l10n · translation · localization · placeholders · icu plural · locale · hindi

Field type

Dependencies

Pairs well with