mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
docs(site): add i18n type reference pages and review fixes
Add Locale, BuiltInLocale, TranslationParams, Translations, and Translator reference pages plus createTranslator. Cross-link types from concept and guides; fix React examples and register-locale satisfies pattern. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,13 +23,18 @@ Video.js translates control labels, ARIA text, tooltips, and error copy through
|
||||
```
|
||||
|
||||
```tsx title="react"
|
||||
<html lang="es">
|
||||
<Provider>
|
||||
<VideoSkin>
|
||||
<Video src="..." playsInline />
|
||||
</VideoSkin>
|
||||
</Provider>
|
||||
</html>
|
||||
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>
|
||||
<VideoSkin>
|
||||
<Video src="..." playsInline />
|
||||
</VideoSkin>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Register a locale once (or rely on lazy-loaded built-in packs), set `lang`, and skins pick up translated strings automatically.
|
||||
@@ -38,7 +43,7 @@ Register a locale once (or rely on lazy-loaded built-in packs), set `lang`, and
|
||||
|
||||
Core controls expose keys, not visible labels. `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. See `packages/core/src/core/i18n/types.ts` for the full key list.
|
||||
Keys 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 `seekForward: 'Seek forward {seconds} seconds'` and `timeRemainingPhrase: '{duration} remaining'`.
|
||||
|
||||
@@ -147,6 +152,7 @@ For zero flash-of-English on SSR or locale switches, pass `translations` directl
|
||||
|
||||
## See also
|
||||
|
||||
- <DocsLink slug="reference/locale">`Locale`</DocsLink>, <DocsLink slug="reference/translations">`Translations`</DocsLink>, <DocsLink slug="reference/translator">`Translator`</DocsLink> — core types
|
||||
- <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>
|
||||
|
||||
@@ -12,7 +12,7 @@ This guide is for **contributors** adding or updating shipped packs — app auth
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Familiarity with <DocsLink slug="concepts/i18n">Internationalization</DocsLink> and `TranslationParams`
|
||||
- Familiarity with <DocsLink slug="concepts/i18n">Internationalization</DocsLink> and <DocsLink slug="reference/translation-params">`TranslationParams`</DocsLink>
|
||||
- English defaults in `packages/core/src/core/i18n/locales/en.ts` as the source of keys
|
||||
|
||||
## 1. Add the locale file
|
||||
|
||||
@@ -71,12 +71,12 @@ Preset skins use `Container`, which includes <DocsLink slug="reference/i18n-prov
|
||||
```ts title="my-es.ts"
|
||||
import type { Translations } from '@videojs/core/i18n';
|
||||
|
||||
const es: Partial<Translations> = {
|
||||
const es = {
|
||||
play: 'Reproducir',
|
||||
pause: 'Pausa',
|
||||
mute: 'Silenciar',
|
||||
unmute: 'Activar sonido',
|
||||
};
|
||||
} satisfies Partial<Translations>;
|
||||
|
||||
export default es;
|
||||
```
|
||||
@@ -127,5 +127,6 @@ Load your module after the player script, before playback starts.
|
||||
## What's next?
|
||||
|
||||
- <DocsLink slug="how-to/i18n-override-translations">Override individual keys</DocsLink>
|
||||
- <DocsLink slug="reference/translations">`Translations`</DocsLink> type
|
||||
- <DocsLink slug="how-to/i18n-switch-locale">Switch locale at runtime</DocsLink>
|
||||
- <DocsLink slug="reference/register-i18n">`registerI18n` reference</DocsLink>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: BuiltInLocale
|
||||
description: Union of shipped BCP 47 locale tags with autocomplete in TypeScript
|
||||
---
|
||||
|
||||
import DocsLink from '@/components/docs/DocsLink.astro';
|
||||
|
||||
`BuiltInLocale` narrows <DocsLink slug="reference/locale">`Locale`</DocsLink> to tags with shipped translation packs in `@videojs/core/i18n/locales/*`. TypeScript suggests these tags when you call `registerI18n`, `loadLocale`, or import locale modules.
|
||||
|
||||
## Import
|
||||
|
||||
```ts
|
||||
import type { BuiltInLocale } from '@videojs/core/i18n';
|
||||
```
|
||||
|
||||
Runtime lists are also exported:
|
||||
|
||||
```ts
|
||||
import { BUILT_IN_LOCALES, LOCALE_ALIAS_TAGS, SHIPPED_LOCALE_TAGS } from '@videojs/core/i18n';
|
||||
```
|
||||
|
||||
## Definition
|
||||
|
||||
```ts
|
||||
type BuiltInLocale =
|
||||
| (typeof BUILT_IN_LOCALES)[number]
|
||||
| (typeof LOCALE_ALIAS_TAGS)[number];
|
||||
```
|
||||
|
||||
`BUILT_IN_LOCALES` lists regional packs (`es`, `pt-BR`, `zh-CN`, …). `LOCALE_ALIAS_TAGS` adds shorthand tags (`pt`, `zh`) that resolve to regional packs through the lookup chain.
|
||||
|
||||
## Lazy loading
|
||||
|
||||
Providers call `loadLocale(tag)` for tags in `SHIPPED_LOCALE_TAGS` when a pack is not already registered. Explicit `registerI18n` or CDN locale modules skip the async gap on first paint.
|
||||
|
||||
## Examples
|
||||
|
||||
```ts
|
||||
import es from '@videojs/react/i18n/locales/es';
|
||||
|
||||
registerI18n('es', es); // 'es' autocompletes as BuiltInLocale
|
||||
```
|
||||
|
||||
Custom app locales (`'xx'`) use `Locale` but are not members of `BuiltInLocale`.
|
||||
|
||||
## Related
|
||||
|
||||
- <DocsLink slug="reference/locale">`Locale`</DocsLink>
|
||||
- <DocsLink slug="how-to/i18n-add-built-in-locale">Add a built-in locale (contributors)</DocsLink>
|
||||
- <DocsLink slug="how-to/i18n-register-locale">Register a custom locale</DocsLink>
|
||||
@@ -15,7 +15,10 @@ import FrameworkCase from "@/components/docs/FrameworkCase.astro";
|
||||
import { createI18n } from '@videojs/react/i18n';
|
||||
|
||||
const { I18nProvider, useTranslator } = createI18n({
|
||||
loadLocale: async (tag) => import(`./locales/${tag}.json`),
|
||||
loadLocale: async (tag) => {
|
||||
const mod = await import(`@videojs/react/i18n/locales/${tag}`);
|
||||
return mod.default;
|
||||
},
|
||||
});
|
||||
|
||||
function App() {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: createTranslator
|
||||
description: Build a typed translator from a resolved translation map
|
||||
---
|
||||
|
||||
import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
|
||||
import DocsLink from "@/components/docs/DocsLink.astro";
|
||||
|
||||
`createTranslator` wraps a <DocsLink slug="reference/translations">`Translations`</DocsLink> map and returns a <DocsLink slug="reference/translator">`Translator`</DocsLink>. Providers call this internally after merging registry, lazy, and prop layers — use it directly for custom UI outside built-in mixins.
|
||||
|
||||
```ts
|
||||
import { createTranslator, getI18nTranslations } from '@videojs/core/i18n';
|
||||
|
||||
const t = createTranslator(getI18nTranslations('fr'), 'fr');
|
||||
t('play');
|
||||
t('seekForward', { seconds: 5 });
|
||||
```
|
||||
|
||||
<UtilReference util="createTranslator" />
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: Locale
|
||||
description: BCP 47 language tag type for i18n registry and provider APIs
|
||||
---
|
||||
|
||||
import DocsLink from '@/components/docs/DocsLink.astro';
|
||||
|
||||
`Locale` is the BCP 47 tag type used by <DocsLink slug="reference/register-i18n">`registerI18n`</DocsLink>, providers, and <DocsLink slug="reference/translator">`Translator`</DocsLink>. Shipped packs autocomplete as <DocsLink slug="reference/built-in-locale">`BuiltInLocale`</DocsLink>; any other tag remains valid at runtime.
|
||||
|
||||
## Import
|
||||
|
||||
```ts
|
||||
import type { Locale } from '@videojs/core/i18n';
|
||||
// or @videojs/html/i18n, @videojs/react/i18n
|
||||
```
|
||||
|
||||
## Definition
|
||||
|
||||
```ts
|
||||
type Locale = BuiltInLocale | (string & {});
|
||||
```
|
||||
|
||||
The `(string & {})` pattern keeps custom tags (`'xx'`, `'en-US'`) type-safe without losing autocomplete for built-ins.
|
||||
|
||||
## Resolution
|
||||
|
||||
Providers and `getI18nTranslations` normalize tags and walk the parent chain (`es-MX` → `es` → `en`) via `localeLookupChain`. See <DocsLink slug="concepts/i18n">Internationalization</DocsLink> for explicit vs ambient resolution.
|
||||
|
||||
## Examples
|
||||
|
||||
```ts
|
||||
const es: Locale = 'es';
|
||||
const custom: Locale = 'en-US';
|
||||
const regional: Locale = 'pt-BR';
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- <DocsLink slug="reference/built-in-locale">`BuiltInLocale`</DocsLink>
|
||||
- <DocsLink slug="reference/register-i18n">`registerI18n`</DocsLink>
|
||||
- <DocsLink slug="how-to/i18n-switch-locale">Switch locale dynamically</DocsLink>
|
||||
@@ -8,7 +8,7 @@ import DocsLink from "@/components/docs/DocsLink.astro";
|
||||
|
||||
`registerI18n` merges a partial translation map into the process-wide registry for a locale tag. English defaults are registered when `@videojs/core/i18n` loads; call `registerI18n` for custom locales or to patch shipped packs before the player renders.
|
||||
|
||||
Import from `@videojs/core/i18n`, `@videojs/html/i18n`, or `@videojs/react/i18n`. Keys are opaque camelCase tokens (`play`, `pause`) — see <DocsLink slug="concepts/i18n">Internationalization</DocsLink>.
|
||||
Import from `@videojs/core/i18n`, `@videojs/html/i18n`, or `@videojs/react/i18n`. Keys are opaque camelCase tokens (`play`, `pause`) — see <DocsLink slug="concepts/i18n">Internationalization</DocsLink> and <DocsLink slug="reference/translations">`Translations`</DocsLink>.
|
||||
|
||||
```ts
|
||||
import { registerI18n } from '@videojs/react/i18n';
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: TranslationParams
|
||||
description: Typed contract for translation keys and their placeholder arguments
|
||||
---
|
||||
|
||||
import DocsLink from '@/components/docs/DocsLink.astro';
|
||||
|
||||
`TranslationParams` maps every opaque translation key to its argument shape. Keys with `never` accept only `t('key')`. Keys with an object accept `t('key', { … })` with typed placeholder names.
|
||||
|
||||
## Import
|
||||
|
||||
```ts
|
||||
import type { TranslationParams } from '@videojs/core/i18n';
|
||||
```
|
||||
|
||||
## Definition
|
||||
|
||||
```ts
|
||||
type TranslationParams = {
|
||||
play: never;
|
||||
pause: never;
|
||||
seekForward: { seconds: number | string };
|
||||
timeRemainingPhrase: { duration: string };
|
||||
// …
|
||||
};
|
||||
```
|
||||
|
||||
English defaults and the full key list live in `packages/core/src/core/i18n/locales/en.ts`. The authoritative TypeScript map is `packages/core/src/core/i18n/types.ts`.
|
||||
|
||||
## Parametric keys
|
||||
|
||||
| Key | Placeholders | Example English value |
|
||||
| --- | --- | --- |
|
||||
| `seekForward` | `{seconds}` | `Seek forward {seconds} seconds` |
|
||||
| `seekBackward` | `{seconds}` | `Seek backward {seconds} seconds` |
|
||||
| `playbackRateAria` | `{rate}` | `Playback rate {rate}` |
|
||||
| `timeSliderValueTextRange` | `{current}`, `{duration}` | `{current} of {duration}` |
|
||||
| `timeRemainingPhrase` | `{duration}` | `{duration} remaining` |
|
||||
| `volumeSliderValueTextMuted` | `{percent}` | `{percent}, muted` |
|
||||
| `indicatorVolumeWithValue` | `{value}` | `Volume {value}` |
|
||||
|
||||
All other keys are plain strings with no parameters.
|
||||
|
||||
## Usage with Translator
|
||||
|
||||
```ts
|
||||
const t: Translator = createTranslator(translations, 'es');
|
||||
|
||||
t('play');
|
||||
t('seekForward', { seconds: 10 });
|
||||
t('timeRemainingPhrase', { duration: '1 minute' });
|
||||
```
|
||||
|
||||
TypeScript rejects missing placeholders when defining <DocsLink slug="reference/translations">`Translations`</DocsLink> overlays:
|
||||
|
||||
```ts
|
||||
registerI18n('es', {
|
||||
seekForward: 'Adelantar', // error: missing {seconds}
|
||||
});
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- <DocsLink slug="reference/translations">`Translations`</DocsLink>
|
||||
- <DocsLink slug="reference/translator">`Translator`</DocsLink>
|
||||
- <DocsLink slug="concepts/i18n">Internationalization</DocsLink> — opaque keys overview
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: Translations
|
||||
description: Partial map of opaque translation keys to localized strings
|
||||
---
|
||||
|
||||
import DocsLink from '@/components/docs/DocsLink.astro';
|
||||
|
||||
`Translations` is the shape for locale packs passed to <DocsLink slug="reference/register-i18n">`registerI18n`</DocsLink>, the React `translations` prop on <DocsLink slug="reference/i18n-provider">`I18nProvider`</DocsLink>, and <DocsLink slug="reference/create-translator">`createTranslator`</DocsLink>. Every entry is optional — missing keys fall back through the BCP 47 chain to English.
|
||||
|
||||
## Import
|
||||
|
||||
```ts
|
||||
import type { Translations } from '@videojs/core/i18n';
|
||||
```
|
||||
|
||||
## Definition
|
||||
|
||||
```ts
|
||||
type Translations = {
|
||||
[K in keyof TranslationParams]?: TranslationParams[K] extends never
|
||||
? string
|
||||
: /* parametric keys must include required {placeholder} tokens */
|
||||
string;
|
||||
};
|
||||
```
|
||||
|
||||
Parametric values must include the same `{placeholder}` substrings as English (`{seconds}`, `{duration}`, …). TypeScript enforces this when you use `satisfies Partial<Translations>`.
|
||||
|
||||
## Examples
|
||||
|
||||
```ts
|
||||
import type { Translations } from '@videojs/core/i18n';
|
||||
|
||||
const es = {
|
||||
play: 'Reproducir',
|
||||
pause: 'Pausa',
|
||||
seekForward: 'Adelantar {seconds} segundos',
|
||||
} satisfies Partial<Translations>;
|
||||
|
||||
registerI18n('es', es);
|
||||
```
|
||||
|
||||
```tsx
|
||||
<I18nProvider locale="de" translations={{ play: 'Abspielen' }} />
|
||||
```
|
||||
|
||||
Only supplied keys override lower layers. See <DocsLink slug="concepts/i18n">Internationalization</DocsLink> for merge priority.
|
||||
|
||||
## Related
|
||||
|
||||
- <DocsLink slug="reference/translation-params">`TranslationParams`</DocsLink>
|
||||
- <DocsLink slug="reference/get-i18n-translations">`getI18nTranslations`</DocsLink>
|
||||
- <DocsLink slug="how-to/i18n-override-translations">Override translation keys</DocsLink>
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: Translator
|
||||
description: Typed function that resolves opaque translation keys to localized strings
|
||||
---
|
||||
|
||||
import DocsLink from '@/components/docs/DocsLink.astro';
|
||||
|
||||
`Translator` is the callable returned by <DocsLink slug="reference/create-translator">`createTranslator`</DocsLink> and <DocsLink slug="reference/use-translator">`useTranslator`</DocsLink>. It turns opaque keys from core controls into localized copy and interpolates `{placeholder}` tokens when params are required.
|
||||
|
||||
## Import
|
||||
|
||||
```ts
|
||||
import type { Translator } from '@videojs/core/i18n';
|
||||
```
|
||||
|
||||
## Definition
|
||||
|
||||
```ts
|
||||
type Translator = <K extends keyof TranslationParams>(
|
||||
key: K,
|
||||
...args: TranslationParams[K] extends never ? [] : [params: TranslationParams[K]]
|
||||
) => string;
|
||||
```
|
||||
|
||||
- Plain keys: `t('play')`
|
||||
- Parametric keys: `t('seekForward', { seconds: 10 })`
|
||||
|
||||
Missing keys in the active map resolve to the key string (`'play'`) so partial locale packs degrade visibly during development.
|
||||
|
||||
## Create manually
|
||||
|
||||
```ts
|
||||
import { createTranslator, getI18nTranslations } from '@videojs/core/i18n';
|
||||
|
||||
const t = createTranslator(getI18nTranslations('pt-BR'), 'pt-BR');
|
||||
t('pause'); // localized or key fallback
|
||||
```
|
||||
|
||||
## React hook
|
||||
|
||||
```tsx
|
||||
import { useTranslator } from '@videojs/react/i18n';
|
||||
|
||||
function Label() {
|
||||
const t = useTranslator();
|
||||
return <span>{t('play')}</span>;
|
||||
}
|
||||
```
|
||||
|
||||
Control components resolve keys from core `getLabel()` through `resolveControlLabel` / `resolveControlAttrs` — you rarely call `t()` directly unless building custom UI.
|
||||
|
||||
## Related
|
||||
|
||||
- <DocsLink slug="reference/create-translator">`createTranslator`</DocsLink>
|
||||
- <DocsLink slug="reference/use-translator">`useTranslator`</DocsLink>
|
||||
- <DocsLink slug="reference/translation-params">`TranslationParams`</DocsLink>
|
||||
@@ -165,6 +165,18 @@ export const sidebar: Sidebar = [
|
||||
{ slug: 'reference/get-i18n-translations', sidebarLabel: 'getI18nTranslations' },
|
||||
{ slug: 'reference/has-registered-i18n', sidebarLabel: 'hasRegisteredI18n' },
|
||||
{ slug: 'reference/on-i18n-registry-change', sidebarLabel: 'onI18nRegistryChange' },
|
||||
{ slug: 'reference/create-translator', sidebarLabel: 'createTranslator' },
|
||||
{
|
||||
sidebarLabel: 'Types',
|
||||
defaultOpen: false,
|
||||
contents: [
|
||||
{ slug: 'reference/built-in-locale', sidebarLabel: 'BuiltInLocale' },
|
||||
{ slug: 'reference/locale', sidebarLabel: 'Locale' },
|
||||
{ slug: 'reference/translation-params', sidebarLabel: 'TranslationParams' },
|
||||
{ slug: 'reference/translations', sidebarLabel: 'Translations' },
|
||||
{ slug: 'reference/translator', sidebarLabel: 'Translator' },
|
||||
],
|
||||
},
|
||||
{ slug: 'reference/feature-buffer' },
|
||||
{ slug: 'reference/feature-controls' },
|
||||
{ slug: 'reference/feature-error' },
|
||||
|
||||
Reference in New Issue
Block a user