Archify Viewer Internationalization and Locale: Complete Implementation Guide
The Archify Viewer uses a lightweight i18n engine that replaces {{i18n:key}} placeholders in HTML templates with localized strings from JSON dictionaries, supporting dynamic locale switching, RTL languages, and accessibility without page reloads.
The tt-a1i/archify repository implements a modular internationalization system for its document viewer component. This Archify viewer internationalization and locale architecture separates presentation from content by storing all user-visible strings as external JSON resources. The system loads translations asynchronously at runtime, enabling seamless language switching while maintaining full accessibility compliance.
How the Archify Viewer i18n Pipeline Works
Template Markup with Placeholders
All static text in the viewer interface is defined using placeholder syntax rather than hard-coded strings. In viewer/template.source.html, developers write UI labels as {{i18n:viewer.toolbar.actions}} markers. These placeholders remain in the DOM until the i18n engine processes them during initialization. This approach ensures that the HTML template contains no embedded text, making localization a data-driven concern.
Locale Selection and Detection
When the viewer boots, the system determines the active language through a cascading fallback sequence. First, it inspects the URL for a locale= query parameter. If absent, it checks navigator.language to detect the browser's preferred language, finally defaulting to "en" if neither source provides a valid locale. The resolved language code is stored in the global viewerLocale variable, making it accessible to all viewer components.
Dictionary Loading and Caching
The i18n engine loads translation data by fetching /viewer/locales/${viewerLocale}.json asynchronously. The loadDictionary() function in viewer/i18n.js performs this request and caches the resulting JSON object in the viewerDict global variable for the session duration. If the requested locale file does not exist, the engine automatically falls back to loading en.json, ensuring the UI remains functional even with incomplete translations.
Runtime Placeholder Substitution
After dictionary loading completes, the applyTranslations() function traverses the DOM using document.createTreeWalker() to identify text nodes containing {{i18n:([\w.]+)}} patterns. It extracts each key, looks up the corresponding value in viewerDict, and replaces the placeholder with the translated string. This process also updates ARIA attributes, tooltips, and button titles to maintain accessibility standards across all supported languages.
Dynamic Locale Switching
The viewer supports runtime language changes without requiring a full page refresh. UI controls in viewer/template.source.html include data-locale attributes that trigger dictionary reloading when clicked. The engine swaps the cached dictionary and re-runs the placeholder substitution logic, instantly updating all visible text while preserving the current application state.
Edge Cases and Accessibility Features
Handling Missing Translation Keys
If a translation key exists in the template but is absent from the selected dictionary, the engine implements a two-tier fallback strategy. It first attempts to retrieve the string from the default English dictionary. If the key remains missing, the engine leaves the raw placeholder ({{i18n:key}}) visible in the UI, providing immediate visual feedback to developers about incomplete localization coverage during testing phases.
Right-to-Left (RTL) Language Support
The i18n engine automatically detects RTL scripts such as Arabic and Hebrew through a lookup table within viewer/i18n.js. When the active viewerLocale matches an RTL language, the system adds dir="rtl" to the root <html> element. This attribute triggers browser-native layout mirroring, ensuring proper text alignment and UI component positioning for right-to-left reading contexts.
Locale-Aware Sorting
UI components that display sorted lists, such as the lens selector in viewer/semantic-lens.js, utilize String.prototype.localeCompare() with the active locale parameter. This method guarantees culturally correct alphabetical ordering that respects language-specific collation rules. Line 47 of semantic-lens.js demonstrates this implementation, ensuring that item sequences match user expectations regardless of the selected language.
Extending the System: Adding New Languages
1. Create the translation file. Add a new JSON file under viewer/locales/ named after the ISO language tag (e.g., fr.json for French). Populate the file with key-value pairs matching the existing dictionary schema used in en.json.
2. Expose the language option. Append a button element to the locale menu in viewer/template.source.html using the pattern <button data-locale="fr">Français</button>. The existing event listener automatically recognizes this control through the data-locale attribute.
3. Verify the implementation. Test the new translation by appending ?locale=fr to the viewer URL. Confirm that all {{i18n:...}} placeholders render the French strings and that no raw placeholders remain visible.
Summary
- The Archify Viewer stores all UI strings as
{{i18n:key}}placeholders inviewer/template.source.html, separating content from presentation. - Locale selection follows a priority chain: URL parameter →
navigator.language→ default"en", stored in the globalviewerLocalevariable. - The
loadDictionary()function inviewer/i18n.jsfetches JSON files fromviewer/locales/and caches them inviewerDictfor the session. - Runtime translation uses DOM TreeWalker to find and replace placeholders, while supporting dynamic locale changes without page reloads.
- RTL languages automatically trigger
dir="rtl"on the root HTML element, andlocaleCompare()inviewer/semantic-lens.jsensures proper alphabetical sorting.
Frequently Asked Questions
How does Archify Viewer determine which language to display?
The viewer checks three sources in sequence: first, the locale query parameter in the URL; second, the browser's navigator.language setting; and finally, a hardcoded default of "en". The first valid locale found becomes the active language stored in viewerLocale and used for all subsequent translation operations.
What happens if a translation key is missing from the current locale?
The system implements a fallback chain where missing keys retrieve values from the English dictionary first. If the key remains absent from the default locale, the raw placeholder text (e.g., {{i18n:missing.key}}) remains visible in the UI. This behavior aids developers in identifying untranslated strings during development and testing phases.
How do I add a new language to the Archify Viewer?
Create a JSON file in viewer/locales/ using the ISO language code as the filename (e.g., de.json), populate it with translated key-value pairs matching the existing schema, and add a corresponding button with data-locale="de" to the language menu in viewer/template.source.html. The existing i18n infrastructure will automatically load and apply the new translations when selected.
Does Archify Viewer support right-to-left languages like Arabic and Hebrew?
Yes, the i18n engine includes RTL detection that automatically applies dir="rtl" to the root HTML element when the active locale uses a right-to-left script. This ensures proper text directionality and layout mirroring without requiring manual CSS adjustments or separate template files for RTL languages.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →