feat(i18n): use translate=no attribute in code sensitive renderings - #2697
feat(i18n): use translate=no attribute in code sensitive renderings#2697displague wants to merge 4 commits into
Conversation
displague
left a comment
There was a problem hiding this comment.
This PR is in draft and not considered to be complete. I believe I've seen <div> used for some text elements in Redoc renderings. In the prompt for this change I hinted that likely candidates for change would be <span> elements.
I don't believe <code> needs to be decorated the same way, but we could easily add that if we can not assume translation services block those elements.
|
I see the |
Signed-off-by: Marques Johansson <marques@displague.com>
- Restore the original `Field.tsx` button structure; the property name and
parent-name prefix stay inside the clickable button, only `translate="no"`
is added.
- Mark the whole `.redoc-json` block with `translate="no"` rather than relying
solely on per-token spans.
- Cover the left-hand (description column) values that were still translatable:
type names/formats, schema patterns, example/default/const values, extension
values, constraints, and enum values. Applied via `.attrs()` on the shared
styled elements in `common-elements/fields.ts` so every call site is covered
centrally, and drop the now-redundant inline attribute on `ConstraintItem`.
- Leave prose translatable: `TypePrefix` ("Array of"), `TypeTitle` (schema
title), `RecursiveLabel`, deprecation/required labels, and descriptions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8199abf to
cb833de
Compare
Found it — rebased onto latest The left/description column renders through the shared styled elements in
Plus Left translatable on purpose: Two other fixes in this push:
276 tests pass; 5 snapshots updated to record the new attribute. |
Fix a false positive:
- `ConstraintItem` is Redoc-authored English prose from `humanizeConstraints()`
("non-empty", "unique", ">= 5 characters", "[ 1 .. 10 ] items", "multiple of
3"), not spec-derived code. It must stay translatable, so the attribute added
in the first pass is removed.
Close the remaining gaps:
- `StyledPre` — every Prism-highlighted sample: request samples (curl/JS/Python
etc.), non-JSON payload/response examples, external-example error output. This
was the largest omission. Applied to `StyledPre` rather than the shared
`PrismDiv` base, since `StyledMarkdownBlock` also derives from `PrismDiv` and
renders prose.
- Markdown `code`/`codespan` — fenced blocks and inline spans in descriptions
are still code; the surrounding prose stays translatable. Verified DOMPurify
preserves `translate` under `options.sanitize`.
- Security identifiers, previously bare `<code>`: API key parameter name, HTTP
auth scheme, bearer format, OAuth flow type, authorization/token/refresh/
connect URLs, and scope names (plus the `ScopeName` element).
- HTTP verbs in the sidebar and callback titles, matching `HttpVerb` in
`Endpoint`. The `type="hook"` badge is only marked when it shows the verb, so
the `l('webhook')` label stays translatable.
- Callback names — OpenAPI runtime expressions, e.g. `{$request.body#/url}`.
- Response status codes (`Code`).
- Media type labels (`MimeLabel`, both definitions).
- `x-` extension names.
- `fieldParentsName` prefix in `Field.tsx`, which rendered parent property names
as bare text outside the marked span.
Deliberately left translatable: `TypePrefix` ("Array of"), `TypeTitle`, schema
titles, `RecursiveLabel`, required/optional/deprecated labels, constraints, all
`l()` labels, `UnderlinedHeader` section headings, sidebar `sidebarLabel`
summaries, `info.title`, and descriptions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Did a full pass over every rendering surface rather than just the One false positive, removed
The largest gap:
|
Snapshots recorded the attribute incidentally, but nothing asserted it, and several changed surfaces (code samples, media type labels, callback titles, extension keys) had no assertion at all. Adds `translateNo.test.tsx` with both directions: - code-sensitive surfaces are marked: type names, patterns, example/default values, Prism-highlighted samples via `SourceCode`, the `.redoc-json` container, OAuth scope names, flow type and URLs, callback verb and name, and `x-` extension keys; - prose stays translatable: humanized constraints, `TypePrefix`, `TypeTitle`, and `RecursiveLabel`. The negative cases are the regression guard for the `ConstraintItem` fix — `humanizeConstraints()` emits English prose, so marking it was wrong. Verified each assertion is load-bearing by stripping the attribute from the sources under test and confirming 10/11 fail, then separately marking `TypePrefix`/`TypeTitle`/`RecursiveLabel` to confirm the 11th fails too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
@AlexVarchuk I compared notes (with Claude) against two other PRs in the a11n and i18n space and made some improvements here to get the PR to cover the right elements and to get it more inline with repo expectations. I'm hoping these updates and review comments are in the direction. |
What/Why/How?
Adds
translate="no", a W3C standard HTML attribute described at https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/translate, and described in the issue linked below. This hints localization tools (Google Translate and others) to avoid translation of data/type sensitive sections of Redoc rendered OpenAPI specs. Many sites may exclude their Redoc pages from translation today because the outcome would be unpredictable. By addingtranslate="no"the translators and translation tools will know to leave these sections untranslated.Reference
Fixes #2696
Tests
npm test(unit + license check): 290 tests, 29 suites, 52 snapshots — all passing.npm run lint: clean (one pre-existing warning insrc/components/RedocStandalone.tsx, untouched by this PR).npm run prettier: no changes.npm run ts-check: clean.src/components/__tests__/translateNo.test.tsx, which asserts the attribute in both directions: code-sensitive surfaces are marked, and Redoc-authored prose is not. Each assertion was verified to be load-bearing by stripping the attribute from the sources under test and confirming the tests fail.src/services/__tests__/mdtranslate.test.tsfor the Markdown renderer, including a check that surrounding prose stays translatable.museum.yaml) vianpm start.npm run e2ewas not run:@redocly/workerize-loaderis listed inpackage.jsonbut missing from the local install, so the standalone bundle does not boot and all 26 specs fail. I confirmed this is pre-existing and unrelated by building and running e2e on an unmodifiedupstream/main, which fails identically. The Markdown change wraps<pre>/<code>, so I checkedMarkdown/styled.elements.tsxfor>/sibling selectors — all rules are descendant-based (code {},pre {},pre code {}), so styling is unaffected.Screenshots (optional)
Check yourself