Skip to content

i18n(a11y): clarify translator context for accessibility terminology - #17118

Open
AKnassa wants to merge 1 commit into
GoogleChrome:mainfrom
AKnassa:i18n-a11y-translator-context
Open

i18n(a11y): clarify translator context for accessibility terminology#17118
AKnassa wants to merge 1 commit into
GoogleChrome:mainfrom
AKnassa:i18n-a11y-translator-context

Conversation

@AKnassa

@AKnassa AKnassa commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Issue #17113 reports that the Slovak locale systematically mistranslates accessibility terminology — Dostupnosť ("availability") where Prístupnosť ("accessibility") is meant, and dostupný názov where prístupný názov ("accessible name") is meant.

This PR does not edit sk.json, and it is not a fix for #17113. It addresses the upstream cause: several of the affected UIStrings give translators no context to tell the two senses of "accessibility" apart. Some give none at all —

/** Title of the Agent Accessibility group of audits. */
agentAccessibilityGroupTitle: 'Agent Accessibility',

A translator seeing that has no way to know whether "Accessibility" means usable by people with disabilities or reachable/up. In Slovak those are different words.

This appends a translator note to the 42 descriptions behind the terminology anchors: the bare Accessibility label, and the terms of art accessible name, accessibility tree, and accessible text alternative.

Why not just fix sk.json?

shared/localization/locales/*.json are marked linguist-generated=true (.gitattributes:2) and are replaced wholesale by the periodic i18n: import commits that carry translations out of Google's Translation Console (core/lib/i18n/README.md, "Translation done in the Google TC pipeline"). A hand-edit would pass CI and then be silently reverted on the next import. The @description comment is the only in-repo lever that reaches a translator.

What this actually achieves — and what it doesn't

Per core/lib/i18n/README.md, TC's message ID is a hash of message and meaning, and resolveMessageCollisions() copies description into meaning only for colliding messages. Diffing the generated en-US.ctc.json before/after:

count effect
messages changed 0 no user-visible text changes
placeholders changed 0
descriptions changed 42 translators see the new context
meaning added / removed 0 / 0 no collision created or resolved
meaning values changed 8 new TC message ID → re-translated

So, plainly:

  • 8 stringsaria-meter-name, aria-progressbar-name, aria-tooltip-name, aria-treeitem-name × (title, failureTitle) — share a placeholdered message, so their meaning is their description. Editing it changes their TC ID. These will be re-sent for translation in all 46 locales. Per the README, fixed collisions "cost real money" — flagging that explicitly so you can weigh it. It is unavoidable if these strings are to gain context.
  • The other 34 keep their message and have no meaning, so their TC IDs are unchanged and their existing translations are retained. They gain context for whenever a translator next looks at them.

Consequently the strings at the heart of #17113 — the Accessibility category label and the Agent Accessibility group title — are in the second group. Their current Slovak translations will not change as a result of this PR. Correcting those requires someone with Translation Console access to fix the Slovak term. I could not find any in-repo mechanism (glossary, term list, override map) that a community contributor could use instead; if one exists I'd be glad to use it.

This PR is a prerequisite for getting the translation right, not the correction itself.

Scope

Glossed the ambiguous single-word labels and the coined ARIA terms. Deliberately left alone the ~11 remaining strings from the issue where "accessibility" appears in ordinary prose that already disambiguates it (aria-roles.js, aria-required-children.js, aria-required-parent.js, aria-allowed-role.js, empty-heading.js, seo/link-text.js, webmcp-schema-validity.js, the three a11y category descriptions in default-config.js, and helpUseCaseSnapshot1). Happy to extend if you'd rather they were consistent.

Each note closes with the same canonical sentence, reused verbatim, following the convention in core/audits/agentic/llms-txt.js.

Two pairs of strings must keep byte-identical descriptions or they flip from an allowed collision to a disallowed one and trip checkKnownFixedCollisions: a11yCategoryTitle/categoryAccessibility (message Accessibility), and agentAccessibilityGroupTitle/Description across both config files. Kept identical — and verified by fault injection: desyncing either pair makes yarn i18n:collect-strings exit 1 with the expected collision-allowlist error (before any file is written), while a lone edit to one of the four legitimately-colliding ARIA descriptions still passes. Runtime lookup of edited keys via format.getFormatted() was also spot-checked in en-US and sk.

Verification

yarn i18n:checks          exit 0   ✅ PASS. All strings have been collected.
yarn diff:sample-json     exit 0   ✅ PASS. No change in LHR.
yarn type-check           exit 0
yarn lint  (full repo)    exit 0
yarn mocha (full suite)   2526 passing, 9 pending, 2 failing*
yarn unit-flow            50 passing

* The 2 failures (build-bundle-test.js, build-lightrider-bundles-test.js) fail identically on unmodified main in a bare local checkout — esbuild cannot resolve the host lighthouse package from node_modules/lighthouse-plugin-soft-navigation (same four errors, byte-identical, both sides). yarn diff:flow-sample-json likewise fails identically on unmodified main (a Node-version errorStack frame absent from the committed baseline); its failing diff is byte-for-byte the same with and without this change.

Every changed line in the diff is a single-line JSDoc comment (machine-checked: zero non-comment changed lines). Runtime lookup of edited keys via format.getFormatted() verified in en-US and sk.

Refs #17113. Thanks to @rraddatch for the very thorough report.

@google-cla

google-cla Bot commented Jul 9, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@AKnassa
AKnassa marked this pull request as ready for review July 9, 2026 01:08
@AKnassa
AKnassa requested a review from a team as a code owner July 9, 2026 01:08
@AKnassa
AKnassa requested review from connorjclark and removed request for a team July 9, 2026 01:08
Several accessibility UIStrings carry translator descriptions that never
disambiguate "accessibility" (usability for people with disabilities) from
"availability". In languages where those are separate words, translators have
picked the wrong one: the Slovak locale renders the Accessibility category as
"Dostupnosť" (availability) rather than "Prístupnosť", and "accessible name" as
"dostupný názov" rather than "prístupný názov".

Some of the affected strings had no usable context at all, e.g.

    /** Title of the Agent Accessibility group of audits. */
    agentAccessibilityGroupTitle: 'Agent Accessibility',

Append a translator note to the 42 descriptions behind the terminology anchors:
the bare "Accessibility" label, and the terms of art "accessible name",
"accessibility tree" and "accessible text alternative". Each note glosses the
term, states that it does not mean "available", and closes with one canonical
instruction reused verbatim, following the convention already used in
core/audits/agentic/llms-txt.js.

No en-US message or placeholder changes; comments only.

Refs GoogleChrome#17113
@AKnassa
AKnassa force-pushed the i18n-a11y-translator-context branch from aad8227 to 7a1d647 Compare July 9, 2026 01:14
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.

1 participant