# Archify Viewer Internationalization and Locale: Complete Implementation Guide

> Implement Archify viewer internationalization and locale effortlessly. Learn how the lightweight i18n engine supports dynamic locale switching RTL languages and accessibility without page reloads.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: how-to-guide
- Published: 2026-09-13

---

**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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/fr.json) for French). Populate the file with key-value pairs matching the existing dictionary schema used in [`en.json`](https://github.com/tt-a1i/archify/blob/main/en.json).

**2. Expose the language option.** Append a button element to the locale menu in [`viewer/template.source.html`](https://github.com/tt-a1i/archify/blob/main/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 in [`viewer/template.source.html`](https://github.com/tt-a1i/archify/blob/main/viewer/template.source.html), separating content from presentation.
- Locale selection follows a priority chain: URL parameter → `navigator.language` → default `"en"`, stored in the global `viewerLocale` variable.
- The `loadDictionary()` function in [`viewer/i18n.js`](https://github.com/tt-a1i/archify/blob/main/viewer/i18n.js) fetches JSON files from `viewer/locales/` and caches them in `viewerDict` for 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, and `localeCompare()` in [`viewer/semantic-lens.js`](https://github.com/tt-a1i/archify/blob/main/viewer/semantic-lens.js) ensures 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`](https://github.com/tt-a1i/archify/blob/main/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`](https://github.com/tt-a1i/archify/blob/main/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.