VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Translate Like a Pro | 7340 — egui and eframe Rust Localization, Catalogs, Unicode Fonts, Stable IDs and WASM QA

egui and eframe localization lets Rust developers build a multilingual immediate-mode interface without losing the state of windows, editable fields or user settings. If you are searching for how to internationalize an egui Rust app, load CJK fonts, change language in eframe, keep widget IDs stable or ship a localized WebAssembly UI, this guide explains a practical catalog-and-testing architecture.

egui is an immediate-mode GUI library, not a built-in automatic translation service. Developers normally provide their own message catalog or a Rust localization library, then choose the correct text as widgets are built each frame. The egui documentation explains that persistent widget IDs are important for remembered state, while Context::set_fonts() can supply additional fonts beyond the default Latin and Cyrillic coverage. This makes localization a combined problem of messages, Unicode, widget identity and rendering.

Our running example is Beacon Ledger, a fictional desktop and browser app for reviewing small project records and making timed decisions. It has windows, expandable headings, editable notes, destructive confirmations, search results and localized status messages. We will build the translation route, inspect Rust state handling and fonts, test native and WASM releases and finish with thirty-two practical troubleshooting cases and a four-week implementation plan.

Quick answer: a practical implementation route

  • Work in egui/eframe message catalogs, fonts and persistent IDs and identify egui’s immediate-mode redraw model and stable Id handling for stateful widgets.
  • Keep the Rust keyed JSON, Fluent or gettext resources selected by application policy outside the application action model.
  • Create a typed message catalog or integrate a Rust localization library; do not rely on egui to translate text automatically.
  • Keep egui::Id and persistent window identifiers separate from translated captions.
  • Use context.set_fonts() or supported version-specific font APIs for scripts beyond default coverage.
  • Refresh views by selecting text from current locale state and requesting a repaint when needed.
  • Test both native eframe bundles and actual WASM deployment, including assets, input methods and accessibility.

Who this guide helps and how to use it

This guide is for developers, translators, testers and technical writers shipping egui and eframe Rust GUI applications interfaces across language markets. The running example is Beacon Ledger, a fictional Rust record-review tool that filters project items, opens persistent panels, lets users annotate records and exports audit notes. Rather than pretending that a language switch is just a word replacement, we follow the same interface through source extraction, translation, state changes, packaging, accessibility review and a real release. The examples are explanatory, not a claim that any particular engine or library provides all of these features automatically.

Begin with the quick route above if you need a decision now. Continue into the detailed platform mechanisms if you are implementing the feature, or jump to a troubleshooting case that resembles your failure. The final release checklist and four-week plan turn the explanation into a manageable project. Where an API behaves differently by version, check the official reference linked at the end against your pinned dependency before shipping.

Contents

  • Core principles for a multilingual interface
  • egui/eframe message catalogs, fonts and persistent IDs: platform-specific implementation choices
  • A worked deployment example
  • Thirty-two practical troubleshooting cases
  • Four-week implementation plan
  • Release and editorial checklist
  • Frequently asked questions
  • Documentation and related guides

Core principles: building dependable localization in egui and eframe Rust GUI applications

1. Define the reader’s actual task

Decide what people are trying to accomplish, not just which sentence looks easy to translate. A button that commits an irreversible action needs explicit wording; a heading may tolerate a freer phrasing. Treat labels, notifications, validation messages, tooltips and documentation as separate editorial contexts. In egui and eframe Rust GUI applications, this becomes concrete when a destructive dialog asks whether a reviewed project should be deleted. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Create a source-message inventory organized by screen, action, audience and consequence. For every string identify its owner, where it is shown, how it is triggered and what would happen if it were misunderstood. For Beacon Ledger, one useful test is expand a panel, change from English to German and confirm it remains expanded. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. A translated caption must not be the hash seed for persistent state where identity should be stable. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

2. Separate message keys from application logic

A translated caption is presentation, not an identifier. Message keys should remain stable when a designer changes the English wording or when a translator chooses a more natural sentence. In egui and eframe Rust GUI applications, this becomes concrete when the current Rust locale state resolves stable message keys into strings each frame. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Build a language-neutral action model: the code decides what action occurs, while the catalog only supplies its explanation. A change in target-language words must not change file operations, settings or saved documents. For Beacon Ledger, one useful test is enter a Japanese project name into an egui text field and export it unchanged. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. Font additions need deliberate glyph and memory review on every renderer. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

3. Choose a locale and explicit fallback

Language selection is not simply guessing from a two-letter country code. Application language, document language, operating-system preferences, accessibility settings and text direction can disagree. In egui and eframe Rust GUI applications, this becomes concrete when a browser’s accept-language differs from the app’s saved locale preference. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Specify a supported language list and a fallback order. Make the selected locale visible, persist it where appropriate, and let the user correct an incorrect automatic choice without losing work. For Beacon Ledger, one useful test is replace all labels with a test catalog while preserving stable widget IDs. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. Immediate-mode rendering simplifies refresh but does not guarantee that every message came from the catalog. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

4. Collect strings and prevent omissions

Strings disappear from translation projects because they are buried in exception handlers, debug paths, file dialogs or source-generated interfaces. A successful home-screen screenshot is not evidence of complete coverage. In egui and eframe Rust GUI applications, this becomes concrete when a custom widget includes an English literal not found by catalog audits. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Inventory every reachable state, including errors, empty datasets, permission failures and first-run screens. Use both extraction and exploratory testing, with a human reviewing what automation cannot discover. For Beacon Ledger, one useful test is deploy the WebAssembly bundle without paths to local development assets. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. A browser deployment has packaging and input differences from a native eframe executable. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

5. Protect placeholders and variable values

Values inserted into translated sentences may be file names, counters, units, person names or user-created content. They must not be silently translated, reordered incorrectly or mistaken for executable formatting symbols. In egui and eframe Rust GUI applications, this becomes concrete when a list row displays a variable record count and selected owner. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Define expected placeholder names and types alongside the message. Give translators examples of singular and plural quantities, negative numbers, long paths and missing values before approving a catalog. For Beacon Ledger, one useful test is open and close two windows with different translated headings without mixing state. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. A translated caption must not be the hash seed for persistent state where identity should be stable. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

6. Handle plurals and grammatical context

English singular-versus-plural is not a universal rule. Some languages have several grammatical categories; others use no visible inflection for the same count. English text concatenation can also trap a noun in the wrong case. In egui and eframe Rust GUI applications, this becomes concrete when a message says one issue or several issues. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Represent complete messages and plural categories with suitable language rules. If the chosen catalog format cannot express that complexity, design an application-owned formatter instead of assuming a single replace operation is enough. For Beacon Ledger, one useful test is disable a catalog and verify that core actions remain understandable in source language. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. Font additions need deliberate glyph and memory review on every renderer. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

7. Treat Unicode, font coverage and shaping separately

UTF-8 encoding ensures bytes can represent characters, but does not guarantee the renderer has the glyphs or shapes complex scripts correctly. A visually empty square is a rendering failure, not proof that translation data is missing. In egui and eframe Rust GUI applications, this becomes concrete when the default font cannot render a Thai or Japanese project name. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Test accented Latin, Cyrillic, CJK, Arabic, Devanagari, combining marks and emoji only where the product claims support. Record both character coverage and script shaping limits rather than treating a font filename as proof. For Beacon Ledger, one useful test is expand a panel, change from English to German and confirm it remains expanded. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. Immediate-mode rendering simplifies refresh but does not guarantee that every message came from the catalog. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

8. Design layouts for length and direction

Translated text may be shorter or much longer than English, with different word breaks and reading order. A fixed-size dialog that works in one language can conceal the very instruction needed to complete a task. In egui and eframe Rust GUI applications, this becomes concrete when a translated panel title becomes too wide for its dock area. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Use flexible spacing, wrapping and scrollable long explanations. Verify right-to-left content separately from right-to-left interface flow; a successful glyph test does not mean buttons and navigation mirror correctly. For Beacon Ledger, one useful test is enter a Japanese project name into an egui text field and export it unchanged. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. A browser deployment has packaging and input differences from a native eframe executable. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

9. Preserve user-authored and imported data

User text is not part of a static interface catalog. A message editor, file path, search phrase, audio preset name or imported project label must remain the user’s own data unless they explicitly request translation. In egui and eframe Rust GUI applications, this becomes concrete when user-entered notes should remain verbatim in all interface languages. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Localize surrounding instructions without rewriting stored values. Test save, reopen, copy, paste, undo and export under several interface languages to ensure content identity survives. For Beacon Ledger, one useful test is replace all labels with a test catalog while preserving stable widget IDs. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. A translated caption must not be the hash seed for persistent state where identity should be stable. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

10. Keep keyboard and accessibility meaning

Shortcut letters, focus order, screen-reader names, error alerts, accessible hints and spoken labels all need independent review. A translated visible caption is not automatically a usable accessible interface. In egui and eframe Rust GUI applications, this becomes concrete when a persistent egui Id controls a collapsible panel even when caption text changes. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Test real keyboards and assistive technologies where the platform permits. Preserve shortcut actions and focus identity while checking whether the translated wording is spoken or displayed correctly. For Beacon Ledger, one useful test is deploy the WebAssembly bundle without paths to local development assets. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. Font additions need deliberate glyph and memory review on every renderer. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

11. Package language resources reliably

An application launched from its build directory can read files that disappear once it is installed, copied to another operating system or run without network access. It may look translated in development and revert to English in production. In egui and eframe Rust GUI applications, this becomes concrete when a WASM bundle must include catalog and font assets that native code can load differently. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Build a release inventory of catalogs, fonts, images, licenses and locale configuration. Install the exact shipping artifact on a clean machine and test without access to the developer’s source tree. For Beacon Ledger, one useful test is open and close two windows with different translated headings without mixing state. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. Immediate-mode rendering simplifies refresh but does not guarantee that every message came from the catalog. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

12. Make release tests reproducible

A single happy-path screenshot cannot verify translated errors, long text, formatting, plural forms, offline operation or multiple application instances. Useful tests describe a state, an action and an observable outcome. In egui and eframe Rust GUI applications, this becomes concrete when eframe app storage and browser storage may preserve preferences differently. That connection is worth writing down because a translator may see an isolated phrase while a tester sees the entire interaction.

Create a language-by-platform matrix. Retain example inputs, exact build versions, expected visible results and screenshots or logs so a later translation update can be compared against a known baseline. For Beacon Ledger, one useful test is disable a catalog and verify that core actions remain understandable in source language. Make a screen recording or short defect note when the result differs. It is better to discover one precise failure in a small language pilot than to send a much larger unverified catalog into production.

Keep the distinction between visible language and application behavior clear. A browser deployment has packaging and input differences from a native eframe executable. The acceptance test should name the translated view and the underlying value independently; otherwise a correct-looking screenshot can conceal a functional regression.

egui/eframe message catalogs, fonts and persistent IDs: platform-specific implementation choices

13. Understand what egui translates and what it does not

egui constructs an interface through Rust code every frame. It accepts strings for controls but does not decide how those strings should be translated. This freedom lets an app use Fluent, gettext, JSON or a typed enum catalog, but it places responsibility for message completeness on the application.

Define stable message keys and have a small resolver provide the current language text. Use domain-specific contexts for terms such as "Close", "Issue" and "Review". A translator needs to know whether Close refers to dismissing a window or closing a business item.

Route all application-owned visible strings through the resolver, including empty states, accessibility names and error messages. Treat logs and developer diagnostics separately from customer-facing messages.

14. Maintain explicit language state

An eframe app can carry a selected locale in application state. Each frame reads that state and requests the current translation for labels, buttons, status messages and tooltips. Changing the locale then changes the next frame’s text.

Persist the selected language if the product promises preference retention. Specify the fallback for unavailable translations and for a new release that removes a language. Do not assume a browser’s locale is always what the user wants.

When localization must refresh a sleeping interface, the official Context API documents request_repaint(). Use it in the integration context rather than assuming a background state update automatically redraws every viewport.

15. Use stable widget IDs across language changes

egui’s Id reference says IDs track widgets from frame to frame, especially for active interactions and persistent state such as window positions and collapsible regions. Some widgets can use location-based IDs, but long-lived state should have an identity that remains stable when layout or labels change.

Use explicit stable salts or an appropriate persistent ID for stateful elements. Do not build an ID from the current translated title if you expect a language switch to preserve a window position, panel expansion or focused edit.

Test a view with several repeated rows: expand one, change the language, then confirm the same record remains expanded. A visually correct new title is not success if the user loses place.

16. Distinguish IDs from widget text

A button’s display text and a widget’s state identity serve different purposes. Immediate-mode code can make them look entwined if developers derive both from the same string, but they should be separate values.

Give records stable identifiers from the domain model and build UI IDs using those identifiers. Use translated labels only for display. Where a library helper generates location-based IDs, confirm that dynamic lists and language changes do not move controls unexpectedly.

This matters most for checkboxes, draggable values, windows, popups and any UI where focus or state persists across frames.

17. Add fonts for international scripts

The egui Context documentation states that default fonts cover Latin and Cyrillic but not every script. The documented set_fonts() method replaces font definitions; newer APIs also describe adding fonts depending on the version.

Select a font with legal distribution rights and appropriate glyph coverage. Test CJK, Thai, Arabic and emoji only where the renderer and shaping behavior actually support them. A font can contain glyphs without making mixed-script line-breaking or bidirectional ordering correct.

Watch atlas texture size and startup time. A giant fallback font may solve one screenshot while creating memory pressure for web clients or lower-end machines.

18. Plan for text shaping and RTL limits

Unicode strings, bidirectional order, glyph shaping and widget layout direction are separate concerns. egui’s supported behavior evolves over releases, so avoid broad promises based on one example of non-Latin text.

Test complete sentences, mixed numbers and punctuation, cursor movement, text selection and copy/paste in the pinned version. Where RTL workflow is essential, check whether the framework and integration truly meet the requirement.

If a target script cannot be supported reliably, explain that limitation before offering it in the language picker. Partial visual rendering is not an adequate substitute for usable text editing.

19. Avoid translating stored model data

A UI language affects captions and explanatory text, not record IDs, audit history or user notes. Feeding arbitrary saved content through a message resolver risks turning it into a translation key or changing identity.

In Beacon Ledger, a note typed in Japanese remains the exact same note when the interface changes to French. Record titles originating from user data should be rendered as data, even if a translated control next to them says Export or Delete.

Test save and reopen across locales. For exported files, define the output format separately; localization must not unexpectedly rewrite machine-readable property names.

20. Choose a catalog with adequate grammatical power

Simple Rust HashMaps or JSON tables can work for short labels, but plurals, select expressions, noun cases and grammatical context may need more capable message formatting. Fluent and other libraries offer structured alternatives, subject to their own API contracts.

Start by listing actual grammar requirements, not by adopting the first crate found. Preserve placeholder names and types, and put complete sentences into messages rather than concatenating English fragments.

For a search result count, test zero, one, two and many records in every promised language. A UI that shows the right number with the wrong grammar is not fully localized.

21. Revisit layout and text measurement

egui has automatic layout facilities, but a translated heading can still cause wrapping or squeeze other controls. Immediate-mode layout recalculation is not a guarantee of good information hierarchy.

Test long German captions, Japanese text without spaces, and mixed right-to-left fragments where supported. Use flexible panels, scroll regions and clear truncation behavior. A destructive warning must remain fully readable rather than being cut off behind an ellipsis.

Change font size and zoom in native and browser contexts. Inspect not just whether text appears, but whether the click target, focus ring and explanation remain connected.

22. Account for native versus WASM packaging

eframe can run applications natively or in browsers. The bundle may load font assets and catalogs differently in each target, and browser caching can retain older files after an update.

Decide whether resources are compiled into the binary, shipped alongside it or requested at runtime. Create deterministic asset URLs and version handling for the browser. A release should work without the developer’s filesystem layout.

Test a clean browser profile, offline behavior if claimed, and local persistence only where supported. An app that loads translations in its native build but not after deployment has a packaging defect.

23. Keep accessibility separate from visible labels

egui’s ecosystem includes accessibility support through integrations such as AccessKit, but having a localized visible caption does not automatically prove screen-reader correctness. A UI needs descriptive names, predictable focus and accessible state changes.

Test keyboard navigation, tab order, focus after locale changes, spoken confirmation text and errors. Be particularly careful when the app rebuilds dynamic lists: an accessible user should not lose location merely because a caption is longer.

Document platform-specific accessibility limitations without advertising unverified parity between web and desktop integrations.

24. Test upgrades and dependency compatibility

egui APIs change as the library evolves, and a tutorial for an older release may describe different font setup or widget behavior. Pin egui/eframe versions and verify the matching docs.rs reference.

Keep regression examples for font registration, persistent IDs, saved locale preferences, native builds and WASM builds. Treat catalog updates as software changes that deserve review and a rollback route.

The final test is a user continuing an existing project after an update, with settings, notes and UI state intact despite new translated copy.

A worked egui and eframe Rust GUI applications deployment: Beacon Ledger

Suppose Beacon Ledger is used first by an English-speaking team and later by people working in French, Japanese and Arabic. These are not just three translation files. French makes many controls longer; Japanese tests glyph coverage and line wrapping; Arabic asks whether the text renderer, input method, bidi behavior and interface direction are suitable for the product. Start with one representative screen containing a search field, a numeric value, a destructive confirmation and an error state.

In the English build, record a baseline: open the project, change an option, enter non-Latin text, cancel an unsafe operation and export a file. Capture actual saved values, not just pictures. Then switch to the pilot locale and repeat the same steps with the same test data. If the display changes correctly while saved state and operations remain identical, the team has evidence of localization rather than an unrelated feature variation.

Beacon Ledger has one deliberate stress test: a user expands a specific item and types a Japanese note, switches the entire interface to French, and opens the same item in an offline WASM build without losing any text or panel state. A reviewer should note the source wording, approved translation, expected action, actual outcome, language chosen, target environment and build identifier. Classify failures as catalog, formatting, font, layout, state, packaging or accessibility defects; this prevents every failure from being blamed vaguely on "translation".

Thirty-two practical egui/eframe message catalogs, fonts and persistent IDs troubleshooting cases

1. A translated window loses its position

What you observe: A panel jumps to its initial position after language switching. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Use stable egui IDs not derived from the current translated title. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: The same window location persists across languages. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

2. A collapsible section closes unexpectedly

What you observe: The selected item’s details collapse when its heading is translated. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Assign stable identity from record keys using persistent IDs where appropriate. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Expanded state persists after the next repaint. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

3. A CJK label shows empty squares

What you observe: The default font cannot render the language’s glyphs. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Add a suitable font via supported Context font APIs and check licensing. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Real CJK labels and user-entered names render on all shipped targets. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

4. A font update removes existing glyphs

What you observe: Replacing font definitions removes previous fallback coverage. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Review set_fonts() replacement behavior or use a supported additive font mechanism. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Latin, Cyrillic and target script glyphs all remain present. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

5. WASM font loads but native does not

What you observe: The two builds resolve different resource paths. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Use build-target appropriate asset packaging and record resource origin. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Both distribution targets display the approved script. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

6. A language switch does not repaint

What you observe: External state changes but a sleeping viewport remains old-language. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Request a repaint through Context when language state changes. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: All active views update promptly in the same selected locale. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

7. A translated label becomes an ID

What you observe: Persistent state is created from visible translated text. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Create IDs from stable semantic keys or record identifiers. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: The same widget keeps focus and state after translation. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

8. Two repeated rows share state

What you observe: Expanding one record also expands another. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Use unique per-record salts within persistent widget IDs. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Only the intended row opens regardless of sorted order. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

9. A plural count sounds wrong

What you observe: A translated status always uses English plural logic. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Choose a formatter suitable for destination plural categories. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Zero, one, two and many results read correctly. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

10. A Japanese note gets translated

What you observe: User input is routed through the message table. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Limit the resolver to interface-owned strings, not document contents. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: The note saves and reopens byte-for-byte unchanged. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

11. Web deployment shows English only

What you observe: A bundled JSON catalog is missing from the hosted artifact. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Include and version catalogs correctly for WASM or compile them in. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: A fresh browser deployment loads the reviewed locale. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

12. Native build depends on source paths

What you observe: An app finds catalogs only when launched from Cargo workspace. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Resolve installed resources correctly or include them in the application. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: A clean native installation works offline. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

13. Language preference is lost on refresh

What you observe: Locale exists only in ephemeral UI state. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Persist an allowed locale code through the target’s supported storage path. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: The app starts with the chosen language after restart. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

14. One string key is reused for another meaning

What you observe: Two occurrences of Review have different grammatical senses. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Use contextual keys or structured translations. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Each UI control expresses the intended action. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

15. A dangerous prompt is truncated

What you observe: A long target-language warning ends before the consequence. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Use full wrapping or a scrollable explanation and explicit action labels. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: The user can read and cancel before irreversible deletion. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

16. RTL punctuation appears confusing

What you observe: Mixed numbers and Arabic text display in unexpected order. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Validate bidi and shaping in the exact renderer; do not claim support without proof. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Supported RTL messages read naturally and text editing works. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

17. Input method composition breaks

What you observe: Switching locale recreates a focused text field. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Preserve widget identity and avoid unnecessary state destruction. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: The user can finish a composed character while changing noncritical UI text. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

18. An emoji forces huge texture allocation

What you observe: A new fallback font causes web memory pressure. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Measure font atlas usage and use targeted, licensed font assets. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Both memory footprint and necessary glyph coverage meet release limits. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

19. Tooltips remain in English

What you observe: Tooltips are built from literals outside the resolver. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Include help text in the catalog inventory. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Hover and keyboard help show target-language guidance. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

20. The browser keeps old catalog files

What you observe: Caching mixes a new app binary with an old translation asset. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Use matching resource versions and test hard reload/update flows. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: New code and translation keys agree after deployment. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

21. A file extension gets translated

What you observe: A translated file format label changes the machine-readable filename. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Separate presentation from path and export format data. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Files open and export with unchanged extensions. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

22. A search query changes after switching

What you observe: Input contents are recreated from translated defaults. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Retain search text in the model and update only surrounding labels. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Results and typed query remain stable. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

23. A screen reader announces the wrong action

What you observe: The visible label changes while accessible metadata stays stale. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Test integration-specific accessibility names and state signals. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Spoken information matches the selected language and actual action. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

24. A responsive layout obscures Cancel

What you observe: German text makes a dialog wider than the browser viewport. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Test compact widths and allow essential actions to remain visible. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Cancel and confirmation controls are reachable under supported sizes. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

25. A format placeholder produces panic

What you observe: A catalog entry uses an incompatible argument name. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Validate placeholders against typed source schema before rendering. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: The message formats without panic and preserves all values. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

26. An unsupported locale is offered

What you observe: A language appears in the picker with missing catalog or glyph support. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Gate available choices behind reviewed catalogs and renderer tests. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Only fully supported language options are offered. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

27. A browser’s OS locale overrides choice

What you observe: Auto-detection keeps replacing an explicit language preference. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Define manual choice priority and fallback rules clearly. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: A returning user sees the chosen locale despite browser defaults. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

28. A hidden pop-up uses stale language

What you observe: Popup text was cached before a locale switch. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Resolve messages when the popup opens or invalidate cached localization state. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Newly opened dialogs use the current language. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

29. An upgrade breaks old UI state

What you observe: Widget IDs changed when translated titles were refactored. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Keep semantic IDs stable across versions and test migration where necessary. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Existing panels and settings survive upgrade. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

30. A third-party icon conflicts with label

What you observe: An icon suggests delete while translated text says archive. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Review visible affordances and icon meaning together. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Target-language users correctly identify the operation. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

31. A long list slows down after font changes

What you observe: Dynamic font additions trigger expensive resource rebuilds each frame. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Register fonts at controlled times and inspect texture usage. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: Scrolling and input remain responsive under every locale. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

32. The release passes only native tests

What you observe: Desktop QA misses missing WASM catalogs and IME behavior. This is especially confusing when the rest of the interface appears correctly translated, because users naturally assume that the visible language tells the whole story. Reproduce the situation with a known test file and note the exact locale and application version.

What to inspect and change: Build separate native and web release matrices with real deployment tests. Avoid a cosmetic patch that simply hides the failure. Trace the message from its source through the selected catalog, formatting step, UI component and release artifact; check whichever part is responsible before changing business logic.

What proves the repair: All claimed targets pass the same functional and language criteria. Repeat the check in the source language and one substantially different language, including after closing and restarting the program. A pass means the user receives the right information and the underlying action or data remains correct, not merely that the screenshot looks attractive.

A four-week localization implementation plan

Week 1 — discover scope and establish a baseline

Inventory Beacon Ledger’s visible messages, callback outcomes, errors, settings, shortcuts, dialogs and files. Record where each string originates and which audiences read it. Choose a pilot language deliberately, and identify who will review grammar and functional meaning. Capture an English baseline before touching the catalog so a new defect cannot be mistaken for an old one.

Deliver a list of message owners, a catalog format decision, a supported-locale policy and eight reproducible baseline tests. Confirm that egui’s immediate-mode redraw model and stable Id handling for stateful widgets is understood by the team. Do not promise an Arabic or CJK language option merely because the bytes can be stored.

Week 2 — build the language path

Implement the message store, locale selection, fallback behavior and representative integration points. Wire a safe switch or restart policy; neither choice is inherently wrong if it is transparent. Review Rust keyed JSON, Fluent or gettext resources selected by application policy and build at least one complete pilot flow with placeholders, a plural, a destructive alert, a file operation and an empty state.

Exercise expand a panel, change from English to German and confirm it remains expanded and replace all labels with a test catalog while preserving stable widget IDs. Check invalid catalog handling, stale messages and translated text length. Record the exact source revision and catalog revision used to build the artifact so reviewers can recreate the result.

Week 3 — test meaning and international text

Have a competent target-language reviewer inspect real screens in context, not only a spreadsheet. Test fonts, character entry, wrapping, input methods, keyboard navigation, spoken labels and any limitations of the renderer. Make sure dates, units and number formatting are intentionally chosen rather than accidentally inherited from the developer’s machine.

Try a user expands a specific item and types a Japanese note, switches the entire interface to French, and opens the same item in an offline WASM build without losing any text or panel state. If a language is not fully supported, document the limitation honestly and keep it out of the language picker. Avoid issuing a "complete" badge merely because translation coverage reached 100 percent.

Week 4 — validate shipping artifacts

Build a production package for every supported target and install it in a clean environment. Test a fresh start, an upgrade, an offline launch, locale persistence, multiple windows or instances where relevant, and recovery after missing files. Read each serious warning aloud with the target-language reviewer to confirm its consequence is clear.

Sign off only when the release matrix shows identical functional outcomes in every promised language. Keep a rollback path for an incorrect catalog, preserve source-language fallbacks, and record how reports from international users will reach the maintainers.

Release checklist

  • All visible egui and eframe Rust GUI applications strings have a documented owner and source context.
  • Catalogs under Rust keyed JSON, Fluent or gettext resources selected by application policy have been reviewed against the actual application.
  • Long translations, numeric formats, plural messages and placeholders have been tested.
  • Fonts and scripts work on every officially supported platform.
  • Translated labels never change saved data, configuration keys or execution paths.
  • Input, keyboard use, focus, dialog outcomes and accessibility have been checked.
  • Packaged releases include the correct language resources and licenses.
  • Offline launches and fresh installations behave consistently.
  • Every promised language has a named reviewer and repeatable tests.
  • A rollback and fallback plan exists for errors found after release.

Frequently asked questions

Does egui translate text automatically?

No. The application chooses and supplies localized strings; egui renders the resulting interface.

How can I change language at runtime?

Keep selected locale in application state and render new strings on subsequent frames, requesting repaint when necessary.

Why do panels lose state when the language changes?

Stateful egui widgets rely on stable Id values. Avoid using translated text for persistent identity.

How do I add Japanese or Korean fonts?

Use the font APIs documented for your egui version, such as Context::set_fonts(), and supply suitable fonts with verified glyph coverage.

Are default egui fonts enough for all languages?

No. The official Context docs say the defaults focus on Latin and Cyrillic; other scripts need suitable font resources.

Can I use Fluent or JSON catalogs?

Yes, as an application choice. Select a format based on placeholder, plural, context and build requirements.

Will browser translation assets work like native files?

Not always. WASM deployment has its own bundling, caching and resource loading rules that require direct testing.

Can I translate saved records?

Only as an explicit content-translation feature. Ordinary interface localization must preserve user notes and machine identifiers.

Does font support prove right-to-left correctness?

No. Glyphs, shaping, bidirectional ordering and input behavior are separate requirements.

Does AccessKit guarantee localized accessibility?

No. Integration must be tested for names, focus, keyboard use, spoken states and the selected language.

How can I keep a list row’s identity stable?

Base widget IDs on stable record keys rather than visible translated captions or transient position when persistence matters.

What should block an international release?

Missing critical messages, broken IDs, unreadable scripts, corrupt user data, misleading warnings or untested target-specific packages.

Official documentation and further reading

egui official Rust documentation · egui Context API: fonts and repaint · egui stable widget ID reference · egui source repository and supported integrations

Continue learning about trustworthy translation

This guide focuses on egui/eframe message catalogs, fonts and persistent IDs rather than replacing the general principles of translation. To understand how meaning, precision, audience and evidence travel between languages, follow the wider translation system. For a different software platform, use the series index rather than mixing unrelated APIs in one implementation.

Master Art of Translation · Translate Like a Pro series index · Previous guide in this series