Skip to content

Write the store copy ahead of the release, and translate the app again - #162

Merged
andiwand merged 6 commits into
mainfrom
fill-in-the-translations
Aug 16, 2026
Merged

Write the store copy ahead of the release, and translate the app again#162
andiwand merged 6 commits into
mainfrom
fill-in-the-translations

Conversation

@andiwand

@andiwand andiwand commented Aug 16, 2026

Copy link
Copy Markdown
Member

Two halves of the same problem: the app's text in other languages was either typed in by hand at submission time or missing altogether.

Rebased onto main now that #159, #160 and #161 are in.

The store copy

scripts/store-copy.py 1.41 writes the "What's New" text for every locale before the release, instead of it being typed into App Store Connect and translated by hand during one.

The English comes from the CHANGELOG.md section of that version, or from Unreleased while the heading is still open. Every other locale is translated by an agent of its own, given that locale's store description and the release before it, so the notes keep the words the listing already uses. A second agent of the same language reads each draft back against the English before it is written. Output is checked mechanically - a line for every English line, every line a bullet, under the store's 4000 characters - and a language that comes back wrong is retried, then named so it can be redone on its own with --locales.

It writes files and never uploads. The copy lives in fastlane/metadata/<locale>/changelogs/1.41.txt, one file per version per locale, because App Store Connect keeps only the notes of the submission in flight.

scripts/store-notes.py owns that layout: it checks a version has copy everywhere and stages it into the one-release_notes.txt-per-locale shape deliver reads. The release run checks before it builds, so a missing translation fails in seconds rather than after both apps are up, and a new notes job uploads it afterwards. That job is separate from upload because notes stay editable until the version is submitted, while a build cannot be uploaded twice.

deliver is pointed at a throwaway directory holding nothing but release notes, so the descriptions checked in beside them are never pushed. The stale release_notes.txt files are gone - every one of them still said "Add search functionality for ODF documents".

1.41's copy is written and reviewed in all eleven locales.

The app

Nineteen of the forty-four strings had no translation in any language: every onboarding button, the whole privacy screen, and all of the house ad. Danish, Catalan, Turkish and Czech showed English for most of the remaining twenty-five.

All fifteen languages are now complete, each gone over by a speaker of that language. Beyond the missing strings, that turned up:

  • the Chinese introduction named a different product, 超级文件管理大师
  • the Irish intro_title_edit held the text belonging to intro_title_apps
  • Spanish loading was Catalan, and misspelled
  • Catalan and Czech still offered "Google Cloud Print", a service that no longer exists
  • Russian ok was Cyrillic ОК, a homoglyph of the Latin OK iOS actually shows
  • "one tap away" had come out as a hint, a keyboard key, or a sketch, depending on the language

Terminology now follows Apple's own wording per language, and the German, Turkish and Russian apps agree with their 1.41 release notes on what "edit" is called. Irish and Slovenian name the iOS Settings panes in English, since iOS ships no UI in either language and a translated path is one the user cannot find.

The store descriptions

Every listing but the English one was a translation of an older English listing, in two generations: de-DE, fr-FR, ru and hi were one behind, es-ES, it, pl, pt-BR, sv and tr two behind — those six were around 1400 characters against English's 3454.

All ten are now translated from what the listing says today. What was missing from most of them:

  • six of the nine feature bullets — password-protected documents, keyword search and highlighting, printing, fullscreen, copy text, text-to-speech
  • the entire supported-formats section, which is most of the App Store search surface: PDF, Microsoft Office, iWork, images, audio, video, EPS, DXF, PSD
  • iCloud, OneDrive and Nextcloud from the list of apps files can be opened from
  • the disclosures about ads and feedback, and in several cases "made in Austria"

Individual defects worth naming: Swedish said kontorsvaror — office supplies — for office suite, along with basisk redigering and an untranslated open .odt, .ods och.odp; French called Apple's Numbers "Numéros" and listed Pladao Office twice; Italian had a sentence that stopped mid-air at apri .odt, .ods e .odp senza ; Turkish advertised a small app size that the English dropped long ago; German had lesen , welche and translated Pages as "Seiten".

The 1.41 release notes changed with them. Line one was PDFs are drawn by the app's own engine, so they fit the screen — reviewers in four languages balked at the engine, and two dropped it rather than translate it. It now reads PDFs now fit the screen and behave like every other document, password protected ones included, which is both plainer and covers the password prompt the old line left out. Every locale's line one was updated to match. The rebase then added #160's line about flat XML documents to the English, so all ten translations were rewritten against the finished four-line text - by the script, which is what it is for.

Name, subtitle and keywords

Eight of the ten storefronts showed the English LibreOffice document viewer / View ODT, ODS, ODG, ODP & more; all ten shared one English keyword string. Every one of them also sold a viewer, so no storefront but the English one said the app edits.

A speaker of each language proposed a localized name and subtitle, and a first
round of this branch shipped them. Apple's public lookup API then said what the
two apps are actually called today:

bundle live name price
Pro at.tomtasche.reader OpenDocument Reader Pro, and LibreOffice Dokumentbetrachter / Visionneuse LibreOffice in de and fr $1.99
Lite at.tomtasche.reader.lite1 OpenDocument Reader - view ODT, the same in all eleven storefronts Free

fastlane/metadata/en-US/name.txt matched neither. The checked-in listing had
drifted, so uploading it would have renamed a live app to something nobody chose.

So the names were settled instead of guessed, and they are no longer translated:

name
Pro OpenDocument Reader Pro
Lite OpenDocument Reader

OpenDocument is the format's own name and goes untranslated in every language;
one name is one app that people can pass to each other. Nothing is lost to search
by it, because the App Store indexes name, subtitle and keywords alike — so
LibreOffice and the local words moved into the subtitle, which is empty on both
apps in every storefront today. There is no name.txt under fastlane/metadata
any more; the apps own their names.

Nothing sells the app as an editor. It edits text, but the capability is
young and does not reach every document, so no name, subtitle or keyword claims
it, and each description says it once, quietly, and calls itself a reader.

subtitle keywords
de-DE LibreOffice Dokumente öffnen 100
en-US LibreOffice documents & PDF 95
es-ES Leer documentos de LibreOffice 99
fr-FR Lecteur LibreOffice, ODT, PDF 100
hi LibreOffice दस्तावेज रीडर 90
it Lettore documenti LibreOffice 96
pl Czytnik dokumentów LibreOffice 100
pt-BR Documentos LibreOffice e PDF 96
ru Чтение документов LibreOffice 95
sv Dokumentläsare för LibreOffice 97
tr LibreOffice, PDF belge okuyucu 95

No keyword repeats a word from the name or from its own subtitle — Apple indexes
all three, so a repeat is a wasted slot. Hindi keeps two Devanagari keywords and
otherwise Latin script, because Hindi-locale App Store search skews heavily Latin.

The listing is uploaded now

scripts/store-notes.py became scripts/store-listing.py, and --stage --app pro|lite stages the whole listing rather than the release notes alone. The notes job is now listing, one per app.

What goes up: name, subtitle, description, keywords, the three URLs, copyright, and the version's release notes. What does not: review_information — the account's contact details and the note to the reviewer — and the category files. Those are named in a list in the script rather than globbed, so adding one is a decision.

Both apps get the whole listing. They say almost the same thing, so fastlane/metadata holds what they share and fastlane/metadata-pro / -lite hold the rest, read over it — <app>/all/ into every locale, <app>/<locale>/ into that one.

Two things differ. The name, which has to: an App Store name is unique, so one file each. And the sentence about advertising, which Pro has been carrying for years in every locale without showing an ad since it stopped linking the SDK. Rather than keep two descriptions per locale and let them drift, the shared one holds ${ads} and each app fills it in from its own ads.txt — Lite has eleven, Pro has none, and a fill-in nobody answers leaves nothing behind, the space in front of it included. FILL_INS lists the names one may have, so a misspelt ${adds} is an error rather than a sentence that quietly vanishes from the store.

The first run overwrites what is in App Store Connect for those fields, on both apps, in all eleven locales. That is the point — the checked-in copy is now the source of truth — but it is worth knowing before the run rather than after. Two things to look at first: copyright.txt still says 2019, and Lite's live name loses - view ODT.

Checked

  • every .strings file passes plutil -lint, has all 44 keys in en.lproj order, no duplicates and no empty values
  • every description is under the store's 4000 characters, and every locale's notes are four bullets, in the order the English has them
  • every name and subtitle is within 30 characters, every keyword list within 100, and no keyword repeats its own name or subtitle
  • the release guard passes for 1.41; Fastfile and release.yml parse; the lanes register
  • both upload lanes run end to end locally as far as the credentials, each staging its own full listing for eleven locales
  • staged side by side, Pro and Lite differ in exactly two files per locale: name.txt, and one sentence of description.txt
  • no ${...} survives staging, and no double space is left where one was filled in empty

The App Store Connect call itself needs the repository secrets, so the first real release run is its own proof.

🤖 Generated with Claude Code

@andiwand
andiwand force-pushed the fix-the-edit-workflow branch from c608627 to 8cab066 Compare August 16, 2026 08:23
Base automatically changed from fix-the-edit-workflow to main August 16, 2026 08:29
andiwand and others added 4 commits August 16, 2026 10:29
The "What's New" text was typed into App Store Connect at submission and
translated by hand. scripts/store-copy.py now writes it from the changelog,
one agent per language and a second one reading each draft back, and the
release run uploads it and refuses a version any locale is missing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
Every language but English showed English for the onboarding buttons, the
privacy screen and the banner - nineteen of the forty-four strings. Danish,
Catalan, Turkish and Czech showed it for most of the rest, and the Chinese
introduction named a different app.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
Every listing but the English one was a translation of an older, shorter
listing: six of the nine features and the whole list of formats the app opens
were missing, and so were the notes about ads and where to send feedback. The
Swedish one called an office suite office supplies.

The 1.41 notes say PDFs fit the screen and take a password like everything
else, rather than which engine draws them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
Eight of the ten storefronts showed an English name and subtitle, both saying
the app only reads. Every one showed the same English keywords, so nobody
searching in their own language found it. Each listing now leads with
LibreOffice, says somewhere that it edits, and spends its keywords on words
people there actually type.

The release run uploads all of it, not just the release notes, so the store
says what is written here. Lite still takes the notes alone: a name has to be
unique in the store, and only Pro's listing is checked in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
@andiwand
andiwand force-pushed the fill-in-the-translations branch from 19fee95 to 5f0271a Compare August 16, 2026 08:33
fastlane/metadata is what Pro and Lite share. fastlane/metadata-pro and
-lite hold the rest, read over it. Two things differ: the name, because
the store wants a unique one, and the sentence about ads, which Pro has
been carrying for years without showing any. That one sentence is a
${ads} in the shared description rather than a second copy of it.

The name is no longer translated. OpenDocument is the format's own name,
and the App Store indexes the subtitle just as well, so the local words
and LibreOffice moved down there.

Nothing sells the app as an editor now. It edits text, but not well
enough to promise.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
@andiwand
andiwand requested a lite review from Copilot August 16, 2026 09:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Both were counted up from what was on disk. A locale that lost its
directory, or only its description, simply stopped being a locale: the
check passed with ten, and that storefront kept whatever the console
said. The eleven are written down now.

Same for the listing itself. A field found nowhere was left out of what
is staged, and App Store Connect reads a field it was not given as
"leave this be" - so the run meant to replace the old words would have
kept them instead. The name is the easiest to lose, since each app says
it in one file for all eleven languages.

Both come from the review of the Android half, opendocument-app/OpenDocument.droid#593.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
@andiwand
andiwand merged commit 52d6412 into main Aug 16, 2026
4 checks passed
@andiwand
andiwand deleted the fill-in-the-translations branch August 16, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants