Documentation

Localization

One program in several languages: copy from per-locale catalogs, records seeded per locale, right-to-left layout.

A program declares the languages it ships in the app header. Copy moves into one catalog per language, and the viewer's locale picks which one renders.

Declaring locales

text
1 2 3 app greeting "1.0.0" "A greeting in three languages." locales [en, ar, sl]

en is required. For each locale, a flat JSON catalog sits beside the program at locales/<locale>/<app>.json:

json
1 2 3 4 ▼{ "hello": "Hello from Orb", "cities": "{{n}} cities, seeded in your language" }

Using the catalog

lolo
1 2 3 4 ▼(render-ui main { type: stack, direction: vertical, gap: sm, children: [ { type: typography, content: (i18n/t "hello"), variant: h3 }, { type: typography, content: (i18n/t "cities" { n: (array/len ?data) }), variant: small } ] })

(i18n/t "key") and @locale are render-time: they belong inside render-ui, never in a guard, a set or an emit. orb validate checks the catalogs against the calls: a key missing from any declared locale, placeholders that do not match the parameters, and keys nothing uses are all reported. Keys are qualified with the app's name when the program lowers, so catalogs from many imported behaviors merge without collisions.

Records per locale

A browser-stored entity can seed different rows for each language:

State machine

Greeting

on City · states: 2 · transitions: 4
emitsCitiesLoadedemitsCitiesFailedemitsMOVED
INIT
CitiesLoaded
CitiesFailed
INIT
1loading
nowready
Running live

Hello from Orb

2 cities, seeded in your language

Ljubljana

Riyadh

std-orb-docex-greeting.lolololo
1app std-orb-docex-greeting "1.0.0" 2"std-orb-docex-greeting — one program in three languages: copy from per-locale catalogs, records seeded per locale." 3locales [en, ar, sl] 4 5orbital GreetingOrbital { 6 entity City [persistent: docex_cities, local] { 7 id : string! 8 name : string! 9 instances [ 10 { id: "C-1", name: "Ljubljana" }, 11 { id: "C-2", name: "Riyadh" } 12 ] 13 instances ar [ 14 { id: "C-1", name: "ليوبليانا" }, 15 { id: "C-2", name: "الرياض" } 16 ] 17 instances sl [ 18 { id: "C-1", name: "Ljubljana" }, 19 { id: "C-2", name: "Rijad" } 20 ] 21 } 22 23 trait Greeting -> City [interaction, collection] { 24 initial: loading 25 26 state loading { 27 INIT -> loading 28 (fetch City { emit: { success: CitiesLoaded, failure: CitiesFailed } }) 29 CitiesLoaded -> ready 30 (emit MOVED { event: "CitiesLoaded" }) 31 (render-ui main { type: stack, direction: vertical, gap: sm, children: [ 32 { type: typography, content: (i18n/t "hello"), variant: h3 }, 33 { type: typography, content: (i18n/t "cities" { n: (array/len ?data) }), variant: small, color: muted }, 34 { type: data-list, entity: ?data, fields: [{ name: "name", label: (i18n/t "city"), variant: h4 }] } 35 ] }) 36 CitiesFailed -> ready 37 (emit MOVED { event: "CitiesFailed" }) 38 (render-ui main { type: alert, variant: error, message: ?error }) 39 } 40 41 state ready { 42 INIT -> loading 43 (emit MOVED { event: "INIT" }) 44 (fetch City { emit: { success: CitiesLoaded, failure: CitiesFailed } }) 45 } 46 47 emits { 48 CitiesLoaded { 49 data : [City] 50 } 51 CitiesFailed { 52 error : string 53 } 54 MOVED -> external { 55 event : string! 56 } 57 @description "Each move names the event it took, so the diagram beside the demo can follow it." 58 } 59 } 60 61 page "/greeting" -> Greeting 62}

instances holds the default locale's rows; once one instances <locale> block is written, every other declared locale needs one. Each locale gets its own browser database, so a visitor's records stay in one language.

Routes and direction

A site usually serves each language under a prefix: /, /ar, /sl. A page renders under the locale its path names, and right-to-left locales such as Arabic set dir="rtl" for the whole page. Long-form content, such as an article or these docs, is written once per language as its own behavior rather than as catalog keys.

Writing the program itself in another language

The language's own keywords, tags and operators also exist in Arabic and Slovenian, so a program can be written natively. Your own names (entities, traits, states, events) never translate, so a native program and its English twin lower to the same .orb. orb i18n vocab prints the vocabulary.

Orb

The language where the rule is the program.

© 2026 Almadar. Ljubljana, Slovenia.