Internationalization (i18n)
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Internationalization (i18n) in the Dotorixel project is designed to support a global user base by providing a multi-language interface. The system currently supports three primary languages: English (en), Korean (ko), and Japanese (ja). The implementation focuses on compile-time message generation and URL path-based routing to ensure high performance and SEO compatibility.
The primary goal of the i18n system is to replace hardcoded UI strings with localized messages across all platforms, including the SvelteKit web application and the Apple native shell. In the web shell, this is achieved using Paraglide.js v2, which allows for tree-shakable message bundles and automatic browser language detection.
Sources: tasks/records/036-i18n-paraglide.md:5-11, CLAUDE.md:21-21
Architecture and Tooling
The i18n architecture differs slightly between the web and native platforms, though both aim for feature parity and shared logic where possible.
Web Implementation (Paraglide.js)
The web editor utilizes Paraglide.js, a compiler-based i18n library. Unlike runtime-heavy solutions, Paraglide compiles translation keys into JavaScript functions, ensuring that only the messages actually used in the code are included in the final bundle.
Key architectural components include:
- Message Catalogs: Stored in
messages/{locale}.json, these contain the key-value pairs for translations. - Inlang Integration: Configuration is managed via
project.inlang/settings.json, which defines the source language and available locales. - Vite Plugin: Integrates the compilation step into the build pipeline.
- Reroute Hook: A universal hook in
src/hooks.tshandles locale-prefixed URLs (e.g.,/en/pebble).
Sources: tasks/records/036-i18n-paraglide.md:14-22, CLAUDE.md:21-21
Native Implementation (Apple Shell)
The Apple native shell (SwiftUI) is planned to use String Catalogs (.xcstrings) to reach parity with the web version. This allows the native app to leverage iOS and macOS system-level language preferences.
Sources: issues/013-apple-native-catchup.md:94-94
Data Flow and Routing
Dotorixel uses URL path routing for language selection. This approach ensures that the current language state is persisted in the URL, allowing for direct linking to localized versions of the editor.
Locale Detection and Redirects
The application implements a "preferred language" strategy. When a user visits the root path (/), the system detects the browser's language and redirects to the appropriate localized path.
The redirection logic is handled at the framework level via Paraglide's preferredLanguage strategy, avoiding infinite loops during client-side navigation.
Sources: tasks/records/037-landing-page.md:8-13, tasks/records/037-landing-page.md:38-42
Language Switching
Users can manually switch languages through links on the landing page. Because SvelteKit's client-side navigation does not automatically trigger Paraglide's locale re-detection, these links use a full-page reload.
Sources: tasks/records/037-landing-page.md:18-20, tasks/records/037-landing-page.md:43-44
Component Integration
Localization is applied across the entire UI by replacing static text with message function calls (m.*()).
Localization Coverage
| Component | Localized Elements |
|---|---|
| TopControls | Undo/Redo titles, Canvas dimensions, Export/Clear buttons |
| BottomTools | Tool names (Pencil, Eraser, etc.), Zoom controls |
| ColorPicker | Hex code labels, Aria-labels for sliders |
| Canvas | Pixel art canvas accessibility labels |
| StatusBar | Current tool labels and canvas metadata |
Sources: tasks/records/036-i18n-paraglide.md:46-59
Tool Labels and Messages
A significant refactor involved moving from a static TOOL_LABELS record to a TOOL_MESSAGE function-reference record in the StatusBar component. This ensures that tool names are updated dynamically when the locale changes.
Sources: tasks/records/036-i18n-paraglide.md:31-31, tasks/records/036-i18n-paraglide.md:52-52
Technical Configuration
The project utilizes specific configurations to support the i18n build pipeline.
Inlang Settings
The project.inlang/settings.json file serves as the single source of truth for the i18n system.
{
"sourceLanguageTag": "en",
"languageTags": ["en", "ko", "ja"],
"modules": [
"https://cdn.jsdelivr.net/npm/@inlang/plugin-json@3/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/sdk-js-plugin@3/dist/index.js"
]
}
Note: The actual settings file uses CDN-loaded plugins to manage JSON translations without local npm dependencies.
Sources: tasks/records/036-i18n-paraglide.md:42-42, tasks/records/036-i18n-paraglide.md:68-70
SvelteKit Configuration
To support localized paths in a static Single Page Application (SPA), the svelte.config.js is set to paths.relative: false. This prevents asset 404 errors when navigating within locale-prefixed directories.
Sources: tasks/records/036-i18n-paraglide.md:26-26, tasks/records/036-i18n-paraglide.md:45-45
Conclusion
The internationalization system in Dotorixel provides a robust, compile-time foundation for supporting multiple languages. By utilizing Paraglide.js and URL-based routing, the project achieves a high-performance localized experience that integrates seamlessly with SvelteKit. Future work involves synchronizing these capabilities with the Apple native shell to ensure a consistent experience across all supported platforms.
Sources: tasks/records/036-i18n-paraglide.md:5-11, issues/013-apple-native-catchup.md:94-96