Skip to content

Spanish, and a test that the next language cannot ship unreachable - #469

Merged
thcp merged 3 commits into
mainfrom
i18n-spanish
Aug 26, 2026
Merged

Spanish, and a test that the next language cannot ship unreachable#469
thcp merged 3 commits into
mainfrom
i18n-spanish

Conversation

@thcp

@thcp thcp commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Closes #468
Closes #467

Spanish, contributed by @diegoarusso and offered in #447. He could not open this himself: the repo restricts pull requests to collaborators, which he flagged in that thread. The commit is his, authorship intact, pulled from his fork.

The contribution

One table, 443 keys, plus the LANGUAGES and TRANSLATIONS entries. Nothing else. I reviewed the whole diff rather than the description, since it came from outside: it is data, with no executable code anywhere in it.

Check Result
Key parity against English complete, no extras, no duplicates
Placeholders and HTML tags identical on every string
Plural families one/other, 15 families, matching de and pt
Orthography no ? or ! without its opening ¿ / ¡
Overflow, all five settings tabs in Spanish zero

His "neutral Spanish" claim holds under measurement rather than assertion: archivo seventeen times and fichero never, no ordenador or computadora at all, and the form in eleven places with usted in none.

The domain vocabulary is the part that would have been hardest to get from a translator rather than a musician. tiempo fuerte for downbeat, compás for meter, golpe de batería for drum hit, and tonalidad against tono to keep key and pitch apart where Spanish wants to collapse them.

What I added on top

Four keys. settings.autoDelete.* landed in #464 after his branch was cut, so his table was complete against the English it left. Written to his conventions: pista, eliminar, "no se puede deshacer" from his settings.resetData.desc, "salvo que" from his settings.cookies.desc.

Two lines in _detectDefault, and this is the part worth reading.

Spanish had no branch there, so the table would have shipped unreachable: present in the picker, complete, and never chosen by anyone whose browser said es-MX. While confirming that, French turned out to have the same gap and to have shipped with it. That is #467.

A test, because the line was never the real problem. LANGUAGES, TRANSLATIONS and _detectDefault are three lists that must agree and only the first two were checked by anything. The failure is silent by construction: nothing throws, no warning appears, the picker looks right, and every string is correct the moment the language is chosen. The only symptom is that it never is.

tests/js/i18n-detect.test.mjs drives _detectDefault with the locales a speaker of each shipped language actually sends, and pins what is easy to break while editing that function: pt-PT ahead of pt, case-insensitive matching, and an unknown tag falling back to English rather than throwing. It runs in CI already, since js-syntax executes every tests/js/*.test.mjs.

I confirmed it can fail rather than only pass. Removing the French line again takes it from 42 passed to 39 passed and 3 failed, naming fr, fr-FR and fr-CA.

Verified

All ten tables complete at 443 base keys. Every static/js/*.js passes node --check. All five tests/js suites pass. The 46 browser tests pass. The Spanish overflow audit covers all five settings tabs including the four strings added here, which were the only ones nobody had looked at.

Worth a separate look

The setting that blocked this PR is still in place, and CONTRIBUTING.md invites outside pull requests. Anyone who is not already a collaborator hits the same wall.

diegoarusso and others added 3 commits August 26, 2026 16:02
Adds Spanish (es) to the language table, covering all 461 English keys.

Neutral Spanish throughout, no regional forms, so it reads the same in
Spain and across Latin America.

Domain vocabulary was chosen by a working musician rather than translated
literally, and two English pairs that collapse into one Spanish word were
separated deliberately:

- track -> "pista" and stems -> "stems", so the 60 keys using one and the
  53 using the other stay distinguishable
- key -> "tonalidad" and pitch -> "tono", which both read as "tono"
  otherwise

Mute and Solo stay untranslated as controls, matching how they are spoken
in a studio, while a full sentence uses "silenciado". GRID keeps its
English label: the neutral Spanish word is long enough to overflow the
beatgrid toolbar, and the regional alternative would not read as Spanish
everywhere.

Five strings were shortened after measuring growth against English, so
the settings tabs and the beatgrid toolbar do not overflow.

Only the one/other plural forms are defined, as Spanish has no few/many
and plural() only routes those for Polish.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Spanish table was complete against the English it branched from. It
landed four keys short only because settings.autoDelete.* went into main
afterwards, in #464. Written to match the conventions already in the
table: pista for track, eliminar for delete, "no se puede deshacer" from
settings.resetData.desc, "salvo que" from settings.cookies.desc, and the
tu form used throughout.

_detectDefault also had no branch for es, so a Spanish browser would
have been handed English and the table would only ever have been found
by someone who went looking in Settings. One table covers every es-*
locale, deliberately, because the vocabulary carries no regional forms.

Note for a separate issue: fr has this same gap and always has. A French
browser gets English today. Left alone here rather than fixed in passing,
since it is a different language's bug and predates this branch.

Verified on the merged file rather than in review: all ten tables
complete at 443 base keys, no extras or duplicates; placeholder and
HTML-tag parity across every Spanish string; plural families one/other
matching de and pt; node --check and the four tests/js suites; the 46
browser tests; and an overflow audit in Spanish across all five settings
tabs, which came back clean including the four strings added here.
_detectDefault had branches for pl, ja, zh, de, pt-PT, pt and id, and
none for fr. A browser reporting fr-FR fell through to English. The
French table has been complete for some time and appears in the picker;
it simply was never chosen on its own, so a French speaker had to find
the setting and pick it by hand.

The missing line is the smaller half. LANGUAGES, TRANSLATIONS and
_detectDefault are three lists that have to agree, and only the first
two are checked by anything. The failure mode is silent by construction:
nothing throws, no warning appears, the picker looks right, and every
string is translated the moment the language is selected. The only
symptom is that it never is.

tests/js/i18n-detect.test.mjs now drives _detectDefault with the locales
a speaker of each shipped language actually sends, and fails if any of
them lands somewhere else. It also pins the parts that are easy to break
while editing: pt-PT ahead of pt, case-insensitive matching, and an
unknown tag falling back to English rather than throwing.

Confirmed the test can fail rather than only pass: removing the fr line
again takes it from 42 passed to 39 passed, 3 failed, naming fr, fr-FR
and fr-CA.

_detectDefault is exported for this. It is a pure function of navigator
and has no other caller.
@thcp thcp closed this Aug 26, 2026
@thcp thcp reopened this Aug 26, 2026
@thcp
thcp merged commit 4e94684 into main Aug 26, 2026
10 checks passed
@thcp
thcp deleted the i18n-spanish branch August 26, 2026 19:18
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.

Spanish is missing from a nine-language app French never gets picked automatically, and nothing would catch the next one

2 participants