You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Agent] i18n: convert remaining hardcoded UI strings and add a no-literal-string guard #655
A first pass (commit f0f19245) moved about 120 hardcoded English strings to t() keys: the building plan, the setup wizard, and the specific titles and labels a frontend audit listed. Several surfaces are still mostly literal English:
web/js/components/preact/UI.jsx: the recording video modal, delete and snapshot dialogs, and fullscreen errors. Only the strings the audit listed were converted.
web/js/components/preact/timeline/CalendarPicker.jsx: month and day names and navigation labels.
FisheyeEptzCanvas.jsx: aria and title strings (partly done).
Anything else a sweep finds: JSX text nodes and title= / aria-label= / placeholder= literals across web/js/components/preact/**.
Expected behavior and scope
Sweep web/js for user-visible literals and convert them to t('<namespace>.<key>'), adding the keys to web/public/locales/en.json only. Other locales fall back to English through web/js/i18n.js. Translations are tracked in a separate issue.
Dates, months and weekdays should use Intl.DateTimeFormat with the active locale instead of translation keys where that's possible (CalendarPicker).
Add a guard so the regression doesn't come back. For example, an ESLint rule such as eslint-plugin-i18next's no-literal-string in markup-only mode, scoped to web/js/components/** with an allowlist for technical strings. If the rule is too noisy, a Jest test that scans the JSX for >[A-Z][a-z]+ text nodes is acceptable.
Don't translate log messages, console.* output, CSS class names or API paths.
Acceptance criteria
No user-visible English literals remain in UI.jsx or CalendarPicker.jsx.
The lint or test guard runs in CI and fails on a newly added literal.
en.json keys are named consistently with existing namespaces (recordings.*, timeline.*, live.*, etc.), and keys that already exist are reused, not duplicated.
t() is only called where it's in scope. Watch module-level helpers that have no t, and run eslint --rule 'no-undef: error' on touched files.
Validation
cd web && npx vite build (this is the JSX compile check; npx babel gives false errors), npm run lint, npm test.
Spot-check the UI with the language set to es: converted strings show English (fallback) without raw key names.
Constraints and rollback
Mechanical refactor. Keep PRs reviewable; splitting by directory is fine.
Activity