---
title: createI18n
description: Factory that creates framework i18n helpers with custom loading options
---

import UtilReference from "@/components/docs/api-reference/UtilReference.astro";
import FrameworkCase from "@/components/docs/FrameworkCase.astro";

<FrameworkCase frameworks={["html"]}>

`createI18n` returns a context-bound `ProviderMixin`, `TextMixin`, and `I18nController` for custom elements. Use it when you need a custom locale loader or custom i18n elements. Most apps use `<media-i18n>` and `<media-text>` from `@videojs/html/i18n`.

```ts
import { ReactiveElement } from '@videojs/element';
import { createI18n } from '@videojs/html/i18n';

const { ProviderMixin, TextMixin } = createI18n();

class LocalizedRoot extends ProviderMixin(ReactiveElement) {}
class LocalizedText extends TextMixin(ReactiveElement) {}
```

<UtilReference util="createI18n" />

</FrameworkCase>

<FrameworkCase frameworks={["react"]}>

`createI18n` returns an `I18nProvider`, `useTranslator`, and `useLocale` wired to the shared React i18n context used by the stock skins and controls. Use it when you need options such as a custom locale loader. Most apps use the default exports from `@videojs/react/i18n`.

```tsx
import { createI18n } from '@videojs/react/i18n';

const loaders = {
  ja: () => import('@videojs/react/i18n/locales/ja'),
};

const { I18nProvider, useTranslator } = createI18n({
  loader: async (tag) => {
    const load = loaders[tag as keyof typeof loaders];
    return load ? (await load()).default : undefined;
  },
});

function App() {
  return (
    <I18nProvider locale="ja">
      <Controls />
    </I18nProvider>
  );
}
```

<UtilReference util="createI18n" />

</FrameworkCase>
