From cfb20fb1345caca536fa2fd2b8bb1b6e7240218f Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Wed, 8 Jul 2026 11:56:26 +1000 Subject: [PATCH] fix(i18n): align stack after phrase key rollout --- .../src/dom/locale/merge-locale-overlays.ts | 6 +-- site/src/content/docs/concepts/i18n.mdx | 26 +++++------ .../docs/how-to/i18n-add-built-in-locale.mdx | 18 ++++---- .../how-to/i18n-override-translations.mdx | 26 +++++------ .../docs/how-to/i18n-register-locale.mdx | 24 +++++----- .../docs/reference/built-in-locale.mdx | 8 ++-- .../docs/reference/create-translator.mdx | 4 +- .../docs/reference/get-i18n-translations.mdx | 2 +- .../docs/reference/has-registered-i18n.mdx | 19 -------- .../docs/reference/has-registered-locale.mdx | 19 ++++++++ .../content/docs/reference/i18n-provider.mdx | 2 +- site/src/content/docs/reference/locale.mdx | 2 +- .../docs/reference/media-i18n-provider.mdx | 4 +- .../src/content/docs/reference/media-text.mdx | 10 ++-- .../content/docs/reference/register-i18n.mdx | 6 +-- .../docs/reference/translation-params.mdx | 46 +++++++++---------- .../content/docs/reference/translations.mdx | 10 ++-- .../src/content/docs/reference/translator.mdx | 16 +++---- .../content/docs/reference/use-translator.mdx | 2 +- site/src/docs.config.ts | 2 +- site/src/utils/utilReferenceSlug.ts | 2 +- 21 files changed, 126 insertions(+), 128 deletions(-) delete mode 100644 site/src/content/docs/reference/has-registered-i18n.mdx create mode 100644 site/src/content/docs/reference/has-registered-locale.mdx diff --git a/packages/utils/src/dom/locale/merge-locale-overlays.ts b/packages/utils/src/dom/locale/merge-locale-overlays.ts index 9c0bd116..af189389 100644 --- a/packages/utils/src/dom/locale/merge-locale-overlays.ts +++ b/packages/utils/src/dom/locale/merge-locale-overlays.ts @@ -1,13 +1,13 @@ /** - * Loads overlay layers for each tag in {@link localeLookupChain}, least-specific first, then merges + * Loads overlay layers for each resolved locale key, least-specific first, then merges * most-specific-last (same semantics as the core i18n registry). */ export async function mergeLocaleOverlays( locale: string, load: (tag: string) => Promise | undefined>, - localeLookupChain: (locale: string) => string[] + findKeys: (locale: string) => string[] ): Promise<{ merged: Partial; loadedTags: string[] }> { - const chain = localeLookupChain(locale); + const chain = findKeys(locale); const layers = await Promise.all(chain.map((tag) => load(tag))); const loadedTags: string[] = []; const merged: Partial = {}; diff --git a/site/src/content/docs/concepts/i18n.mdx b/site/src/content/docs/concepts/i18n.mdx index b36f3358..ae6dc408 100644 --- a/site/src/content/docs/concepts/i18n.mdx +++ b/site/src/content/docs/concepts/i18n.mdx @@ -1,13 +1,13 @@ --- title: Internationalization -description: How Video.js translates player UI copy with opaque keys, a global registry, and locale providers +description: How Video.js translates player UI copy with English phrase keys, a global registry, and locale providers --- import FrameworkCase from '@/components/docs/FrameworkCase.astro'; import Aside from '@/components/Aside.astro'; import DocsLink from '@/components/docs/DocsLink.astro'; -Video.js translates control labels, ARIA text, tooltips, and error copy through a single **global registry**. Components ask for strings by **opaque key** (`play`, `pause`, `seekForward`), not by English text, so locale files stay stable when copy changes. +Video.js translates control labels, ARIA text, tooltips, and error copy through a single **global registry**. Components ask for strings by current English phrase (`Play`, `Pause`, `Seek forward {seconds} seconds`), so missing translations stay readable. @@ -44,13 +44,13 @@ export function App() { Register a locale once (or rely on lazy-loaded built-in packs), set `lang`, and skins pick up translated strings automatically. -## Opaque keys +## Phrase keys -Core controls expose keys, not visible labels. `PlayButtonCore.getLabel()` returns `'play'`; the translator turns that into `'Play'`, `'Reproducir'`, or your override. +Core controls expose current English phrases. `PlayButtonCore.getLabel()` returns `'Play'`; the translator turns that into `'Play'`, `'Reproducir'`, or your override. -Keys are typed in `TranslationParams`. TypeScript catches missing `{param}` placeholders and wrong argument names at compile time. +Phrase params are typed in `TranslationParams`. TypeScript catches missing `{param}` placeholders and wrong argument names at compile time. -Parametric strings use `{placeholder}` tokens, for example `seekForward: 'Seek forward {seconds} seconds'` and `timeRemainingPhrase: '{duration} remaining'`. +Parametric strings use `{placeholder}` tokens, for example `'Seek forward {seconds} seconds'` and `'{duration} remaining'`. ## Global registry @@ -60,7 +60,7 @@ Parametric strings use `{placeholder}` tokens, for example `seekForward: 'Seek f | --- | --- | | `registerI18n` | Add or merge a locale layer | | `getI18nTranslations` | Read the merged map for a locale | -| `hasRegisteredI18n` | Check whether a tag is in the registry | +| `hasRegisteredLocale` | Check whether a tag is in the registry | | `onI18nRegistryChange` | Subscribe to registry updates | Import from `@videojs/html/i18n` or `@videojs/react/i18n` depending on your framework. @@ -108,7 +108,7 @@ es-MX → es → en zh-Hant-HK → zh-hant → zh → en ``` -`getI18nTranslations`, lazy `loadLocale`, and providers all use the same chain via `localeLookupChain`. +`getI18nTranslations`, lazy `loadLocale`, and providers all use the same chain via `findLocaleKeys`. ## Merge priority @@ -136,19 +136,19 @@ CDN consumers load self-registering modules: ## Common pitfalls ```tsx -// ❌ Don't: key is the English word; keys are opaque tokens -registerI18n('es', { Play: 'Reproducir' }); +// ❌ Don't: old camelCase keys are ignored +registerI18n('es', { play: 'Reproducir' }); // ✅ Do -registerI18n('es', { play: 'Reproducir' }); +registerI18n('es', { Play: 'Reproducir' }); ``` ```tsx // ❌ Don't: parametric key without the placeholder -registerI18n('es', { seekForward: 'Adelante 10 segundos' }); // TS error: missing {seconds} +registerI18n('es', { 'Seek forward {seconds} seconds': 'Adelante 10 segundos' }); // TS error: missing {seconds} // ✅ Do -registerI18n('es', { seekForward: 'Adelantar {seconds} segundos' }); +registerI18n('es', { 'Seek forward {seconds} seconds': 'Adelantar {seconds} segundos' }); ```