Five-commit i18n cleanup: ~90 new keys, namespace fixes, locale cookie fallback

After a next-intl v4 scaffold landed ~112 keys per language, five follow-up commits over roughly 36 hours worked through the bugs it left behind. The most reusable fix addresses a real quirk in `localePrefix: 'never'` mode that anyone using next-intl v4 with that setting will hit.

i18n

The first two commits (1f2a7f6, b4c96d3) are coverage work: ~80 keys in the first pass across placeholders, aria-labels, button text, alerts, and status labels, then ~11 more in a second pass for inline text nodes a regex sweep missed (AssistantMessage, TRChatPanel, breadcrumbs, empty states). Straightforward but product-specific.

Commit c33fac9 is the one worth keeping. With localePrefix: 'never', getRequestConfig in next-intl v4 doesn't reliably receive the locale from requestLocale. The fix reads the NEXT_LOCALE cookie directly as a fallback in frontend/i18n.ts - ten lines, and also unfreezes the <html lang> attribute, which had been hardcoded to "de".

Commits 198ab24 and 0d6cd6a show what happens when regex-driven translation rewrites go wrong. The sweep changed useTranslations('common') to useTranslations() across 35 components, dropping the common. prefix from key references. That broke keys that actually live in the common namespace. The follow-up commit restores the prefix for those keys - but introduces a new bug: user?.email?.split("common.@")[0] (the regex replaced the literal string "@" inside a split call). Worth studying as a cautionary example of why regex-driven i18n sweeps need thorough review.

So what Skip unless you're running next-intl v4 with `localePrefix: 'never'`, in which case the `c33fac9` cookie-fallback patch in `frontend/i18n.ts` is worth pulling directly. The namespace-prefix churn (commits 4 and 5) is a useful warning about automated i18n rewrites: scope `useTranslations` by namespace and stay consistent rather than dropping to unscoped calls when you span namespaces.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

5 commits from fedec65/bettercallmitch, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
1f2a7f65 fix(i18n): comprehensive translation coverage for EN/DE/FR/IT Federico Cesconi 2026-05-06 ↗ GitHub
commit body
- Add ~80 new translation keys across all 4 language files
- Wire up 40+ components to use useTranslations instead of hardcoded strings
- Fix placeholders, aria-labels, titles, button text, alerts, inline text nodes
- TypeScript compiles cleanly
- Only remaining hardcoded strings are API key format examples
b4c96d34 fix(i18n): second pass - inline text nodes, breadcrumbs, status labels Federico Cesconi 2026-05-06 ↗ GitHub
commit body
- Add 11 more translation keys across all 4 languages
- Fix remaining inline text in AssistantMessage, TRChatPanel, WFColumnViewModal
- Translate breadcrumbs (Workflows, Projects, Assistant)
- Translate status labels (Running, Thinking, Applied Workflow)
- Translate empty states and modal titles
- TypeScript compiles cleanly
c33fac9d fix(i18n): read NEXT_LOCALE cookie directly in getRequestConfig Federico Cesconi 2026-05-06 ↗ GitHub
commit body
- Explicitly read the NEXT_LOCALE cookie in i18n.ts as a fallback
  when requestLocale doesn't detect the locale (common issue with
  localePrefix: 'never' in next-intl v4)
- Use dynamic locale in html lang attribute instead of hardcoded 'de'
- TypeScript compiles cleanly
198ab24c fix(i18n): resolve namespace conflicts in useTranslations Federico Cesconi 2026-05-06 ↗ GitHub
commit body
- Change useTranslations('common') to useTranslations() in 35 components
  that access keys from multiple namespaces
- Strip redundant 'common.' prefix from translation keys
- Fix AssistantWorkflowModal double namespace (assistant.assistant.*)
- TypeScript compiles cleanly, no more MISSING_MESSAGE errors
0d6cd6a0 fix(i18n): restore common. prefix and fix false positives Federico Cesconi 2026-05-07 ↗ GitHub
commit body
- Restore 'common.' namespace prefix for keys under the common namespace
  when using useTranslations() without a namespace argument
- Fix false positives where regex matched non-translation strings:
  document.createElement('a'), import paths, punctuation
- TypeScript compiles cleanly

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-61.md from inside the repo you want the changes in.

⬇ Download capture-thread-61.md