Setting locale translates part of the Admin UI, but most of the visible text is hardcoded English in components. The result is an interface that looks broken rather than untranslated — a Brazilian client of mine reads "Salvar" and "Adicionar" next to "Paragraph", "Bold" and "4 entries" on the same screen.
I ran into this shipping two Keystatic Cloud panels to non-technical clients in Brazil, and I'm currently patching the strings locally with pnpm patch (~750 lines against 0.6.4), which obviously doesn't survive upgrades.
What's covered today
src/app/l10n/* has 27 keys, mostly shell chrome: add, cancel, create, save, search, delete, edit, loading, dashboard, collection(s), singleton(s), plus the git/branch vocabulary.
What isn't
An inventory from 0.6.4, grouped by where it lives. Not exhaustive, but it's everything a content editor hits in a normal session:
Editor toolbar — src/form/fields/markdoc/editor/Toolbar.tsx (and the equivalent in document/DocumentEditor/)
Bold, Italic, Underline, Strikethrough, Code, Superscript, Subscript, Clear formatting, Blockquote, Code block, Image, Table, Divider, Layout, Numbered list, Bullet list, Alt text, Text, Link, Align Start / Align Center / Align End, and the table row/column operations.
Block type menu — same files plus insert-menu.tsx
Paragraph, and `Heading ${level}` built as a template literal, which needs an ICU message rather than a plain key.
Collection and item pages — src/app/CollectionPage.tsx, src/app/ItemPage.tsx
Empty collection, Create the first entry, No results, Loading Entries, Loading Item, Creating entry, Entry not found., Reset changes, Copy entry, Paste entry, Delete entry, Save and duplicate entry, Saving changes, Unsaved, Changed, Preview, View on GitHub.
Dashboard — src/app/dashboard/DashboardCards.tsx, src/app/dashboard/DashboardPage.tsx
pluralize(count, { singular: 'entry', plural: 'entries' }) on the collection cards, Hello, {name}!, Manage Account. The pluralize call needs a plural-rule message, not a string swap.
Auth / Cloud — Log in with Keystatic Cloud, Authenticating, Not found.
Question before any PR
Is this something you want? I'm happy to do the work, but it's a large mechanical change: each string becomes a key plus a JSON file across 34 locales, and I'd rather agree on the shape first than send an unsolicited PR touching hundreds of files.
Specifically:
- Scope. Would you take it in slices (toolbar first, then collection/item pages), or not at all?
- Untranslated locales. When a new key is added, should the other 33 locales get the English string, or be left absent so the formatter falls back?
- Code language names.
Bash, CSS, Python etc. in the code block picker should stay as-is — proper nouns. Assuming that's uncontroversial.
- Setup screens. The GitHub App setup flow is developer-facing and arguably not worth translating. Skip?
Happy to start with the toolbar as a proof of the approach if that's useful.
Setting
localetranslates part of the Admin UI, but most of the visible text is hardcoded English in components. The result is an interface that looks broken rather than untranslated — a Brazilian client of mine reads "Salvar" and "Adicionar" next to "Paragraph", "Bold" and "4 entries" on the same screen.I ran into this shipping two Keystatic Cloud panels to non-technical clients in Brazil, and I'm currently patching the strings locally with
pnpm patch(~750 lines against 0.6.4), which obviously doesn't survive upgrades.What's covered today
src/app/l10n/*has 27 keys, mostly shell chrome:add,cancel,create,save,search,delete,edit,loading,dashboard,collection(s),singleton(s), plus the git/branch vocabulary.What isn't
An inventory from 0.6.4, grouped by where it lives. Not exhaustive, but it's everything a content editor hits in a normal session:
Editor toolbar —
src/form/fields/markdoc/editor/Toolbar.tsx(and the equivalent indocument/DocumentEditor/)Bold,Italic,Underline,Strikethrough,Code,Superscript,Subscript,Clear formatting,Blockquote,Code block,Image,Table,Divider,Layout,Numbered list,Bullet list,Alt text,Text,Link,Align Start/Align Center/Align End, and the table row/column operations.Block type menu — same files plus
insert-menu.tsxParagraph, and`Heading ${level}`built as a template literal, which needs an ICU message rather than a plain key.Collection and item pages —
src/app/CollectionPage.tsx,src/app/ItemPage.tsxEmpty collection,Create the first entry,No results,Loading Entries,Loading Item,Creating entry,Entry not found.,Reset changes,Copy entry,Paste entry,Delete entry,Save and duplicate entry,Saving changes,Unsaved,Changed,Preview,View on GitHub.Dashboard —
src/app/dashboard/DashboardCards.tsx,src/app/dashboard/DashboardPage.tsxpluralize(count, { singular: 'entry', plural: 'entries' })on the collection cards,Hello, {name}!,Manage Account. The pluralize call needs a plural-rule message, not a string swap.Auth / Cloud —
Log in with Keystatic Cloud,Authenticating,Not found.Question before any PR
Is this something you want? I'm happy to do the work, but it's a large mechanical change: each string becomes a key plus a JSON file across 34 locales, and I'd rather agree on the shape first than send an unsolicited PR touching hundreds of files.
Specifically:
Bash,CSS,Pythonetc. in the code block picker should stay as-is — proper nouns. Assuming that's uncontroversial.Happy to start with the toolbar as a proof of the approach if that's useful.