Skip to content

i18n

Ybyra never hardcodes labels. All user-facing text is resolved through a translate function following a key convention.

Key Conventions

Key PatternExampleUsed For
{domain}.fields.{field}person.fields.nameField labels
{domain}.fields.{field}[{state}]person.fields.name[error]Field label with visual state
{domain}.groups.{group}person.groups.basicGroup labels
common.actions.{action}common.actions.createAction labels (shared)

Translate Contract

The translate function has a simple signature:

typescript
type TranslateContract = (key: string) => string

Pass it to hooks:

typescript
const form = useDataForm({
  schema: PersonSchema.provide(),
  scope: Scope.add,
  translate: (key) => i18n.t(key),
  // ...
})

Resolution Helpers

All framework packages provide the same helper functions for label resolution:

typescript
import { resolveFieldLabel, resolveGroupLabel, resolveActionLabel } from '@ybyra/react' // or '@ybyra/vue' or '@ybyra/svelte'

resolveFieldLabel(t, 'person', 'name', '')
// → t('person.fields.name')

resolveFieldLabel(t, 'person', 'name', 'error')
// → t('person.fields.name[error]')

resolveGroupLabel(t, 'person', 'basic')
// → t('person.groups.basic')

resolveActionLabel(t, 'person', 'create')
// → tries t('person.actions.create'), falls back to t('common.actions.create')

Example Translation File

Translations are typically defined as TypeScript objects (see @ybyra/demo for a complete example):

typescript
export const ptBR = {
  common: {
    actions: {
      add: "Adicionar",
      create: "Criar",
      update: "Atualizar",
      cancel: "Cancelar",
      destroy: "Excluir",
      "create.success": "Registro criado com sucesso",
      "update.success": "Registro atualizado com sucesso",
      "destroy.confirm": "Deseja realmente excluir este registro?",
      "destroy.success": "Registro excluído com sucesso",
    },
    table: {
      columns: "Colunas",
      previous: "Anterior",
      next: "Próximo",
      page: "Página {{page}} de {{total}}",
      empty: "Nenhum registro encontrado",
    },
    dialog: { confirm: "Confirmar", cancel: "Cancelar" },
  },
  validation: {
    required: "Campo obrigatório",
    minLength: "Mínimo de {{value}} caracteres",
    maxLength: "Máximo de {{value}} caracteres",
    min: "Valor mínimo é {{value}}",
    max: "Valor máximo é {{value}}",
  },
  person: {
    fields: {
      id: "ID",
      name: "Nome",
      email: "E-mail",
      phone: "Telefone",
      birthDate: "Data de Nascimento",
      active: "Ativo",
      street: "Rua",
      city: "Cidade",
    },
    groups: {
      basic: "Informações Básicas",
      address: "Endereço",
    },
  },
}

Field States

Fields can have visual states (set via the schema proxy). When a state is active, the label key includes the state:

typescript
schema.name.state = 'error'
// Label resolves from: person.fields.name[error]

Define allowed states on a field:

typescript
text().states('error', 'warning', 'new')

Component Contracts and i18n

All component contract methods (toast, dialog) receive i18n keys, not raw strings. The framework automatically resolves the key through the translate contract before displaying the message.

typescript
// ✅ Correct — uses i18n key
component.toast.success('common.actions.create.success')
component.dialog.confirm('common.actions.destroy.confirm')

// ❌ Wrong — raw strings won't be translated
component.toast.success('Record created successfully!')
component.dialog.confirm('Are you sure?')

Common i18n Keys for Actions

KeyTypical Translation
common.actions.create.success"Registro criado com sucesso"
common.actions.create.invalid"Formulário inválido"
common.actions.update.success"Registro atualizado com sucesso"
common.actions.update.invalid"Formulário inválido"
common.actions.destroy.confirm"Deseja realmente remover?"
common.actions.destroy.success"Registro removido com sucesso"
common.dialog.confirm"Confirmar"
common.dialog.cancel"Cancelar"

TIP

You can define custom i18n keys for domain-specific actions. For example, a custom export action could use person.actions.export.confirm and person.actions.export.success.

Released under the MIT License.