Skip to content

BUG-2060-2: DiaryPage initial-load a11y announcement is hardcoded English (not i18n) #2062

Description

@steilerDev

BUG-2060-2: initial-load screen-reader announcement in DiaryPage is hardcoded English, bypassing i18n

Severity: Minor

Component: client/src/pages/DiaryPage/DiaryPage.tsx (Issue #2060 — Diary infinite-scroll rework)

Found in: manual inspection while writing client/src/pages/DiaryPage/DiaryPage.test.tsx for the infinite-scroll rework (i18n testing responsibility, CLAUDE.md "Internationalization & Translation" section: "All user-facing strings must use t() — never hardcode text in JSX").

Steps to Reproduce

  1. Switch the app locale to German (de).
  2. Visit /diary and let the first batch of entries load.
  3. Inspect the live region (role="status", aria-live="polite") that screen readers announce on load.

Expected Behavior

The initial-batch announcement should be translated, consistent with the two other announcement branches in the same effect (infiniteScroll.batchAppendedAnnouncement and infiniteScroll.batchAppendedAndEndAnnouncement, both already correctly wired through t() with an interpolated count).

Actual Behavior

DiaryPage.tsx's announcement effect hardcodes the initial-load announcement in English and never calls t():

useEffect(() => {
  if (fetchSequence === 0 || !announcementRef.current) return;
  if (fetchSequence === 1) {
    announcementRef.current.textContent = `Loaded ${lastBatchCount} entries`;   // <-- hardcoded, not t()
  } else if (!hasMore) {
    announcementRef.current.textContent = t('infiniteScroll.batchAppendedAndEndAnnouncement', {
      count: lastBatchCount,
    });
  } else {
    announcementRef.current.textContent = t('infiniteScroll.batchAppendedAnnouncement', {
      count: lastBatchCount,
    });
  }
}, [fetchSequence, hasMore, lastBatchCount, t]);

This means German-locale users get an English screen-reader announcement ("Loaded 5 entries") on every initial page load, while every other diary infinite-scroll announcement is correctly localized. There is also no corresponding key in client/src/i18n/en/diary.json or client/src/i18n/de/diary.json for this specific "initial load" announcement (the existing infiniteScroll.* keys cover loading/error/retry/end-of-list/append, but not "N entries loaded" for the first batch).

Evidence

client/src/pages/DiaryPage/DiaryPage.tsx, inside the fetchSequence-driven announcement useEffect (search for the template literal `Loaded ${lastBatchCount} entries` — it's the only non-t() branch in that effect). Compare with the sibling branches in the same effect, which both use t('infiniteScroll.batchAppended...').

Suggested Fix Direction (for frontend-developer, not prescriptive)

Add an English key (e.g. infiniteScroll.initialLoadAnnouncement, "{{count}} entries loaded") to client/src/i18n/en/diary.json, have the translator add the German equivalent, and replace the hardcoded template literal with t('infiniteScroll.initialLoadAnnouncement', { count: lastBatchCount }).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions