mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
303 lines
11 KiB
Plaintext
303 lines
11 KiB
Plaintext
---
|
|
title: Internationalization
|
|
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 ships in English by default. Non-English UI is opt-in: mount an i18n provider, then configure its active language. Video.js resolves the matching strings for control labels, ARIA text, tooltips, and error copy.
|
|
|
|
The default i18n path is automatic after you opt in. Built-in locale packs lazy-load on demand, and Chrome can fill missing languages or missing keys through the [Browser Translation API](https://developer.mozilla.org/en-US/docs/Web/API/Translator) when an on-device translation model is already available.
|
|
|
|
Components ask for strings by current English phrase (`Play`, `Pause`, `Seek forward {seconds} seconds`), so missing translations stay readable.
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
```html
|
|
<html lang="es">
|
|
<media-i18n>
|
|
<video-player>
|
|
<video-skin>
|
|
<video src="..." playsinline></video>
|
|
</video-skin>
|
|
</video-player>
|
|
</media-i18n>
|
|
</html>
|
|
```
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
```tsx
|
|
import { I18nProvider } from '@videojs/react/i18n';
|
|
import { Provider, VideoSkin, Video } from '@videojs/react/video';
|
|
|
|
// Set `<html lang="es">` on the document (layout, _document, or index.html)
|
|
export function App() {
|
|
return (
|
|
<Provider>
|
|
<I18nProvider>
|
|
<VideoSkin>
|
|
<Video src="..." playsInline />
|
|
</VideoSkin>
|
|
</I18nProvider>
|
|
</Provider>
|
|
);
|
|
}
|
|
```
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
Mount `<media-i18n>` and set its `lang` attribute, or let it inherit the nearest ancestor `lang`. Built-in packs then load automatically.
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
Mount `I18nProvider` and pass its `locale` prop to force a language, or omit it to inherit `lang`. Built-in packs then load automatically.
|
|
|
|
</FrameworkCase>
|
|
|
|
Registering packs yourself is only needed when you want custom copy, synchronous first paint, SSR, or CDN loading.
|
|
|
|
## Phrase keys
|
|
|
|
Core controls expose current English phrases. `PlayButtonCore.getLabel()` returns `'Play'`; the translator turns that into `'Play'`, `'Reproducir'`, or your override.
|
|
|
|
Phrase params are typed in <DocsLink slug="reference/translation-params">`TranslationParams`</DocsLink>. TypeScript catches missing `{param}` placeholders and wrong argument names at compile time.
|
|
|
|
Parametric strings use `{placeholder}` tokens, for example `'Seek forward {seconds} seconds'` and `'{duration} remaining'`.
|
|
|
|
See <DocsLink slug="reference/translation-phrases">Translation phrases</DocsLink> for every current key and the player UI that uses it.
|
|
|
|
## Global registry
|
|
|
|
`registerI18n(locale, translations)` merges strings into a process-wide map. English (`en`) is pre-registered when the i18n bundle loads, which is why the default player works without setup.
|
|
|
|
| API | Purpose |
|
|
| --- | --- |
|
|
| <DocsLink slug="reference/register-i18n">`registerI18n`</DocsLink> | Add or merge a locale layer |
|
|
| <DocsLink slug="reference/get-i18n-translations">`getI18nTranslations`</DocsLink> | Read the merged map for a locale |
|
|
| <DocsLink slug="reference/has-registered-locale">`hasRegisteredLocale`</DocsLink> | Check whether a tag is in the registry |
|
|
| <DocsLink slug="reference/on-i18n-registry-change">`onI18nRegistryChange`</DocsLink> | Subscribe to registry updates |
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
Import from `@videojs/html/i18n`.
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
Import from `@videojs/react/i18n`.
|
|
|
|
</FrameworkCase>
|
|
|
|
## Opt into a language
|
|
|
|
Leave your app in English by default. To opt into another language, mount the framework provider around the translated player subtree:
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
- Wrap the player in <DocsLink slug="reference/media-i18n">`<media-i18n>`</DocsLink>.
|
|
- Set `<html lang="es">` or `lang="es"` on `<media-i18n>` to opt into Spanish.
|
|
- Video.js lazy-loads the shipped Spanish pack when it is not already registered.
|
|
|
|
Use a separate `<media-i18n>` for standalone controls or players that need different languages on the same page.
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
- Mount <DocsLink slug="reference/i18n-provider">`I18nProvider`</DocsLink> inside `Provider`, around the preset skin.
|
|
- Omit the `locale` prop to inherit `<html lang="es">`, or pass `locale="es"` directly.
|
|
- Video.js lazy-loads the shipped Spanish pack when it is not already registered.
|
|
|
|
Pass the `locale` prop to force a language or `translations` for per-render overrides.
|
|
|
|
</FrameworkCase>
|
|
|
|
If no pack exists, the provider keeps English until a registered pack, lazy-loaded pack, provider override, or supported browser translation layer supplies strings.
|
|
|
|
## Locale resolution
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
`<media-i18n>` resolves its active language in order:
|
|
|
|
1. **Explicit**: its `lang` attribute
|
|
2. **Ambient**: nearest ancestor `[lang]`
|
|
3. **Fallback**: English defaults
|
|
|
|
Changing `<html lang>` re-renders wired controls without remounting the player. An explicit provider `lang` overrides ambient language until you remove or update it.
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
`I18nProvider` resolves its active language in order:
|
|
|
|
1. **Explicit**: its `locale` prop
|
|
2. **Ambient**: `langRootRef` or `<html lang>`
|
|
3. **Fallback**: English defaults
|
|
|
|
Changing `<html lang>` re-renders wired controls without remounting the player. An explicit `locale` prop overrides ambient language until you remove or update it.
|
|
|
|
</FrameworkCase>
|
|
|
|
## BCP 47 fallback
|
|
|
|
Lookups walk a **parent chain**, not sibling locales. `es-MX` falls back to `es`, then `en`, not to `es-419`.
|
|
|
|
```
|
|
es-MX → es → en
|
|
zh-Hant-HK → zh-hant → zh → en
|
|
```
|
|
|
|
`getI18nTranslations`, lazy `loadLocale`, and providers all use the same chain via `findLocaleKeys`.
|
|
|
|
## Merge priority
|
|
|
|
Later layers win over earlier ones:
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
| Layer | Source |
|
|
| --- | --- |
|
|
| 1 (base) | English defaults (`en.ts`) |
|
|
| 2 | Browser Translation API (Chrome, pre-installed model only) |
|
|
| 3 | `registerI18n` / CDN locale modules |
|
|
| 4 | Lazy built-in packs (`loadLocale`) |
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
| Layer | Source |
|
|
| --- | --- |
|
|
| 1 (base) | English defaults (`en.ts`) |
|
|
| 2 | Browser Translation API (Chrome, pre-installed model only) |
|
|
| 3 | `registerI18n` / CDN locale modules |
|
|
| 4 | Lazy built-in packs (`loadLocale`) |
|
|
| 5 (top) | `translations` prop on `I18nProvider` |
|
|
|
|
</FrameworkCase>
|
|
|
|
## Built-in locale packs
|
|
|
|
Providers call `loadLocale` automatically for the active locale chain when a pack is not already registered, so app bundles can split locale packs into async chunks.
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
HTML locale files live under `@videojs/html/i18n/locales/*`.
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
React locale files live under `@videojs/react/i18n/locales/*`.
|
|
|
|
</FrameworkCase>
|
|
|
|
To preload a shipped language without writing a `registerI18n` call, import its side-effect module:
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
```ts
|
|
import '@videojs/html/i18n/locales/es/register';
|
|
```
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
```ts
|
|
import '@videojs/react/i18n/locales/es/register';
|
|
```
|
|
|
|
</FrameworkCase>
|
|
|
|
Import and register a pack manually when you need custom copy or want to preload a fixed language picker. See <DocsLink slug="how-to/i18n-register-locale">Register a locale</DocsLink>.
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
CDN consumers load self-registering modules:
|
|
|
|
```html
|
|
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/html/cdn/video.js"></script>
|
|
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/html/cdn/locales/es.js"></script>
|
|
```
|
|
|
|
</FrameworkCase>
|
|
|
|
## Browser translation
|
|
|
|
After lazy loading runs, Video.js can ask the browser to translate the English registry through the [Browser Translation API](https://developer.mozilla.org/en-US/docs/Web/API/Translator). This currently works in Chrome when `globalThis.Translator` is available and the matching on-device model is already installed.
|
|
|
|
Video.js does not download translation models during normal provider resolution. If Chrome reports the model as unavailable, downloadable, or still downloading, controls keep using the registered, lazy-loaded, or English fallback strings.
|
|
|
|
Browser translation is a fallback, not a replacement for reviewed locale packs. Use shipped packs or your own registered strings for production-critical copy and SSR.
|
|
|
|
## Common pitfalls
|
|
|
|
```ts
|
|
// ❌ Don't: old camelCase keys are ignored
|
|
registerI18n('es', { play: 'Reproducir' });
|
|
|
|
// ✅ Do
|
|
registerI18n('es', { Play: 'Reproducir' });
|
|
```
|
|
|
|
```ts
|
|
// ❌ Don't: parametric key without the placeholder
|
|
registerI18n('es', { 'Seek forward {seconds} seconds': 'Adelante 10 segundos' }); // TS error: missing {seconds}
|
|
|
|
// ✅ Do
|
|
registerI18n('es', { 'Seek forward {seconds} seconds': 'Adelantar {seconds} segundos' });
|
|
```
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
<Aside type="tip">
|
|
For zero flash of English on SSR or locale switches, pass `translations` directly to `I18nProvider` or register the locale before render. See <DocsLink slug="how-to/i18n-ssr">SSR with locale</DocsLink>.
|
|
</Aside>
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
<Aside type="tip">
|
|
For zero flash of English on SSR or locale switches, register the locale before render. See <DocsLink slug="how-to/i18n-ssr">SSR with locale</DocsLink>.
|
|
</Aside>
|
|
|
|
</FrameworkCase>
|
|
|
|
## See also
|
|
|
|
<FrameworkCase frameworks={["html"]}>
|
|
|
|
- <DocsLink slug="reference/media-i18n">`<media-i18n>`</DocsLink>, <DocsLink slug="reference/locale">`Locale`</DocsLink>, <DocsLink slug="reference/translations">`Translations`</DocsLink>, <DocsLink slug="reference/translator">`Translator`</DocsLink>: I18n APIs
|
|
- <DocsLink slug="how-to/i18n-register-locale">Register a custom locale</DocsLink>
|
|
- <DocsLink slug="how-to/i18n-override-translations">Override individual keys</DocsLink>
|
|
- <DocsLink slug="how-to/i18n-switch-locale">Switch locale dynamically</DocsLink>
|
|
- <DocsLink slug="how-to/i18n-ssr">SSR and hydration</DocsLink>
|
|
- <DocsLink slug="concepts/accessibility">Accessibility</DocsLink>: Translated ARIA labels
|
|
|
|
</FrameworkCase>
|
|
|
|
<FrameworkCase frameworks={["react"]}>
|
|
|
|
- <DocsLink slug="reference/i18n-provider">`I18nProvider`</DocsLink>, <DocsLink slug="reference/locale">`Locale`</DocsLink>, <DocsLink slug="reference/translations">`Translations`</DocsLink>, <DocsLink slug="reference/translator">`Translator`</DocsLink>: I18n APIs
|
|
- <DocsLink slug="how-to/i18n-register-locale">Register a custom locale</DocsLink>
|
|
- <DocsLink slug="how-to/i18n-override-translations">Override individual keys</DocsLink>
|
|
- <DocsLink slug="how-to/i18n-switch-locale">Switch locale dynamically</DocsLink>
|
|
- <DocsLink slug="how-to/i18n-ssr">SSR and hydration</DocsLink>
|
|
- <DocsLink slug="concepts/accessibility">Accessibility</DocsLink>: Translated ARIA labels
|
|
|
|
</FrameworkCase>
|