- Add `locales` field to SearchUiIndexConfig (HashMap<lang, translations>)
- Enable operators to configure custom translations via config endpoint
- JavaScript already has i18n support (lang query param, fallback to en)
- Add documentation for operators on how to configure locales
Acceptance: GET /ui/search/{index}?lang=fr returns French UI strings when
fr locale configured; falls back to en.
3.2 KiB
3.2 KiB
Search UI i18n (Internationalization)
Overview
The Search UI supports internationalization (i18n) for operator-supplied translations. This is part of plan §13.21.
How It Works
-
Query Parameter: Users can specify a language via the
langquery parameter:- Example:
GET /ui/search/myindex?lang=fr
- Example:
-
Browser Fallback: If no
langparameter is provided, the UI usesnavigator.language -
Fallback to English: If the requested language is not configured, the UI falls back to English (the default built-in locale)
Configuring Custom Locales
Operators can add custom translations via the POST /_miroir/ui/search/{index}/config endpoint:
curl -X POST "http://miroir:8080/_miroir/ui/search/myindex/config" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin_key>" \
-d '{
"locales": {
"fr": {
"ui.title": "Recherche",
"ui.logo": "Recherche",
"ui.search.placeholder": "Rechercher...",
"ui.search.label": "Recherche",
"ui.search.ariaLabel": "Requête de recherche",
"ui.search.hint": "Tapez pour rechercher. Appuyez sur / pour focus. Utilisez les flèches pour naviguer.",
"ui.search.button": "Rechercher",
"ui.filters": "Filtres",
"ui.sort.label": "Trier:",
"ui.sort.relevance": "Pertinence",
"ui.perPage.label": "Par page:",
"ui.results.empty": "Aucun résultat trouvé",
"ui.results.emptyHint": "Essayez d'ajuster votre recherche ou vos filtres",
"ui.results.count": "{count} résultats ({time}ms)"
}
}
}'
Built-in Translations
The Search UI includes English translations by default in the bundled JavaScript. The t() function handles variable interpolation:
// With interpolation
t('ui.results.count', { count: 42, time: 15 })
// Returns: "42 results (15ms)"
// With French locale
// Returns: "42 résultats (15ms)"
Translation Keys
The following translation keys are supported (with default English values):
UI Labels
ui.title- Page titleui.logo- Logo textui.search.placeholder- Search input placeholderui.search.label- Search labelui.search.ariaLabel- Search ARIA labelui.search.hint- Search keyboard hintui.search.button- Search button ARIA labelui.darkMode.ariaLabel- Dark mode toggle ARIA labelui.filters- Filters button textui.sort.label- Sort selector labelui.sort.relevance- Default sort option textui.perPage.label- Per-page selector label
Results
ui.results.empty- Empty state titleui.results.emptyHint- Empty state hintui.results.didYouMean- "Did you mean" suggestion (use{query}variable)ui.results.count- Result count (use{count}and{time}variables)
Errors
ui.error.noIndex- No index specified errorui.error.searchFailed- Search failed error (use{status}variable)ui.error.initFailed- Init failed error (use{message}variable)ui.error.sessionFailed- Session fetch failed
Accessibility
ui.filters.ariaLabel- Filters ARIA labelui.pagination.ariaLabel- Pagination ARIA labelui.keyboardShortcuts.ariaLabel- Keyboard shortcuts ARIA labelui.keyboardShortcuts.text- Keyboard shortcuts help text