Skip to content

fix(ui): replace all hardcoded frontend strings with i18n translation keys#9013

Open
Pfannkuchensack wants to merge 2 commits intoinvoke-ai:mainfrom
Pfannkuchensack:fix/frontend-i18n-hardcoded-strings
Open

fix(ui): replace all hardcoded frontend strings with i18n translation keys#9013
Pfannkuchensack wants to merge 2 commits intoinvoke-ai:mainfrom
Pfannkuchensack:fix/frontend-i18n-hardcoded-strings

Conversation

@Pfannkuchensack
Copy link
Copy Markdown
Collaborator

@Pfannkuchensack Pfannkuchensack commented Apr 4, 2026

Summary

Remove fallback/defaultValue strings from t() calls, replace hardcoded English text in labels, tooltips, aria-labels, placeholders and JSX content with proper t() calls, and add ~50 missing keys to en.json. Fix incorrect i18n key paths in CanvasObjectImage.ts and a Zoom button aria-label bug in CanvasToolbarScale.tsx.

Related Issues / Discussions

Frontend components added by recent AI-written PRs introduced hardcoded English strings and t() fallback values instead of using proper i18n localization entries. This PR ensures all user-facing frontend text goes through the translation system.

What was fixed

Issue 1: t() calls with fallback/default values (54 occurrences across 12 files)

These used patterns like t('key', 'Fallback') or t('key', { defaultValue: 'Text' }), bypassing the localization file:

File Count Example
TextToolOptions.tsx 18 t('controlLayers.text.bold', { defaultValue: 'Bold' })
CanvasObjectImage.ts 6 t('common.loadingImage', 'Loading Image')
ModelList.tsx 6 t('modelManager.modelsDeleted', { defaultValue: '...' })
PinnedFillColorPickerOverlay.tsx 4 t('controlLayers.fill.switchColors', { defaultValue: '...' })
ToolGradientModeToggle.tsx 4 t('controlLayers.gradient.linear', { defaultValue: 'Linear' })
7 other files 16 Various

Issue 2: Hardcoded strings without t() (~100 occurrences across ~35 files)

Category Count Examples
JSX text content 23 <Button>Fit View</Button>, <Text>No images found</Text>
label="..." props 18 label="Loading", label="Queue Item"
aria-label="..." props 32 aria-label="Upload image", aria-label="Zoom out"
tooltip="..." props 8 tooltip="Image Actions", tooltip="Prompt History"
placeholder="..." props 4 placeholder="Search..."
title="..." / JSX headers 6 <ModalHeader>Crop Image</ModalHeader>

Issue 3: Wrong i18n key paths (2 occurrences)

In CanvasObjectImage.ts, the keys controlLayers.unableToFindImage and controlLayers.unableToLoadImage were used, but the actual keys in en.json are under controlLayers.errors.*. The fallback strings masked this bug — translations would have never worked.

Bonus: Bug fix

In CanvasToolbarScale.tsx, the Zoom In button (with PiMagnifyingGlassPlusBold icon) had aria-label="Zoom out" — fixed to "Zoom in".

New en.json keys added (~50)

Namespace Keys
common editName, fitView, json, minimize, next, noMatchingItems, notifications, openSlider, previous, removeFromCollection, resetView, saveToAssets, settings, toggleRgbHex, zoomIn, zoomOut
prompt promptHistory, clearHistory, usePrompt, searchPrompts
gallery bulkDownloadReady, clickToDownload, loadingGallery, loadingMetadata, noImagesFound
queue queueActionsMenu, queueItem
controlLayers disableReferenceImage, enableReferenceImage, invalidReferenceImage, invertRegion, removeImageFromCollection, selectRefImage
controlLayers.text lineHeight, lineHeightDense, lineHeightNormal, lineHeightSpacious
controlLayers.fill switchColors
controlLayers.autoSwitch doNotAutoSwitch, switchOnStartDesc, switchOnFinishDesc
nodes nodeData
workflows noWorkflowToSave
lora removeLoRA
dynamicPrompts problemGeneratingPrompts
modelManager deleteModelsConfirm, deleteWarning, modelsDeleted, modelsDeleteFailed, someModelsFailedToDelete, modelsDeletedPartial, someModelsDeleted, modelsDeleteError
cropper (new) cropImage, aspectRatio, free, mouseWheelZoom, spaceDragPan, dragCropBoxToAdjust
supportVideos gettingStartedPlaylist, studioSessionsPlaylist, discord, github

used regex

Pattern A: t('key', 'fallback')

rg "t('[^']+',\s*'" --glob '*.{ts,tsx}' src/

Pattern B: t('key', { defaultValue: '...' })

rg "t([^)]defaultValue" --glob '.{ts,tsx}' src/

label="..." props with English text

rg 'label="[A-Z][^"]"' --glob '.tsx' src/ --glob '!.test.'

tooltip="..." props

rg 'tooltip="[A-Z][^"]"' --glob '.tsx' src/ --glob '!.test.'

aria-label="..." props

rg 'aria-label="[A-Z][^"]"' --glob '.tsx' src/ --glob '!.test.'

placeholder="..." props with English text

rg 'placeholder="[A-Z][^"]"' --glob '.tsx' src/ --glob '!.test.'

Hardcoded text in JSX tags (z.B. >Some Text<)

rg '>[A-Z][A-Za-z ]{2,}</' --glob '.tsx' src/ --glob '!.test.*'

QA Instructions

  1. Verify all UI text still displays correctly (no missing translations showing raw keys)
  2. Check the affected components render properly:
    • Text tool options (Font, Size, Bold, Italic, etc.)
    • Crop image modal (buttons, labels, help text)
    • Staging area buttons (auto-switch tooltips)
    • Prompt history popover
    • Gallery grid (loading/empty states)
    • Model manager bulk delete confirmation
    • Queue item detail view
  3. Verify zoom buttons in canvas toolbar have correct aria-labels (Zoom In vs Zoom Out)

Merge Plan

No special merge considerations. Localization-only change with no runtime behavior changes beyond fixing the Zoom button aria-label and the CanvasObjectImage key paths.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Tests added / updated (if applicable) — No tests needed, localization string changes only
  • ❗Changes to a redux slice have a corresponding migration — N/A
  • Documentation added / updated (if applicable) — N/A
  • Updated What's New copy (if doing a release after this PR) — N/A

… keys

Remove fallback/defaultValue strings from t() calls, replace hardcoded
English text in labels, tooltips, aria-labels, placeholders and JSX content
with proper t() calls, and add ~50 missing keys to en.json. Fix incorrect
i18n key paths in CanvasObjectImage.ts and a Zoom button aria-label bug
in CanvasToolbarScale.tsx.
@github-actions github-actions bot added the frontend PRs that change frontend files label Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend PRs that change frontend files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant