Skip to content

Locales

A locale is a language and region a product answers in. The file lists them, and every page, email and template is generated in each.

From the file's words to every locale

Names, fields, codes and prices never change between locales. Filled: what a reader sees.

What every locale gets

locales lists the languages, the first the default. Every Interface that prints words prints them in each.

FamilyWhat it does
The source textThe comments and descriptions in the file are the source; nothing else is typed twice
TranslationsGenerated for each locale at deploy into a file per locale beside the definition, reviewed as a diff, and corrected by a person or an agent
Names that never changeNouns, fields, Verbs, Problem codes, paths and prices are the same in every locale, so code and agents never branch on language
PagesThe landing site, the portal and the docs under a path per locale, such as /de/docs, each with its Markdown twin and an llms.txt per locale
RepliesAccept-Language picks the locale of a reply's words: descriptions, a Problem's detail and its cure; Content-Language names it
MessagesTemplates, notifications, receipts and invoices in each recipient's own preference, then the org's, then the default
FormatsDates, times, numbers and amounts written the locale's way, in the Customer's timezone; prices stay in the currency settlement names
ScriptsRight-to-left languages laid out in every generated UI and email
SearchThe words index of each Noun tokenises per language, so a search in German finds German text
Authored contentA Content item holds a version per locale, each drafted, reviewed and published on its own
TermsThe terms, privacy policy and DPA rendered per locale, with the default locale's text named as the one that governs

Example

The company product answers in English, German and Canadian French.

definition.ts
14 lines
import { define, secret } from 'apis.dev'

/** Any company by its domain, with its headcount and sector. */
export default define({
  name: 'companyfacts', domain: 'companyfacts.apis.dev',
  sources: { firms: { origin: 'https://firms.example.com', key: secret('FIRMS_KEY') } },
  Company: {
    domain:    { type: 'url!#',   from: 'firms', map: 'website' },
    employees: { type: 'number?', from: 'firms', map: 'headcount' },
    sector:    { type: 'string?', from: 'firms', map: 'industry' },
  },
  locales: ['en', 'de', 'fr-CA'],                   // the first is the default
  offer: { 'Company.get': 0.002, 'Company.search': 0.005 },
})

A miss asked in German answers in German; the code, the status and the price stay the same.

Response
HTTP/1.1 404 Not Found
Content-Type: application/problem+json
Content-Language: de
X-Cost: price=0, currency="USD"
X-Request-Id: req_4f2b7d01e9a63c58b0d6

{
  "type": "https://companyfacts.apis.dev/docs/errors#not_found",
  "title": "Not Found",
  "status": 404,
  "detail": "Kein Unternehmen mit der Domain kestrel.example.",
  "code": "not_found",
  "instance": "req_4f2b7d01e9a63c58b0d6"
}

Locales and translations, state by state

A translation is a line of the Version it ships in, so a rollback rolls it back too.

ThingStatesWhat moves it
A localedeclared, translating, reviewed, liveA deploy that adds it; its review; the next deploy serves it on every Interface at once
A translated linegenerated, reviewed, corrected, then stale when its source changesEach deploy; a reviewer; a correction is a diff like any other
A page in a localecurrent, staleIts lines; a stale page serves the default locale's line in its place and says so
A content item's locale versiondrafted, reviewed, published, withdrawnIts author and reviewer, as any authored item

What readers, members and agents meet

  • A reader. The site, the docs and every email in its own language, with dates and amounts written its way.
  • A member. The portal and every UI in its own preference, set once, on every device.
  • A developer. One set of names and codes whatever the language, and docs that read naturally in its own.
  • An agent. Accept-Language for words it shows a person, and names it never has to translate.

Every locale is generated from the file's own words, so a page, a Problem and an email say the same thing in every language.