Localization

The SDK comes with a built-in translation service powered internally by the i18next library. The main focus of the service is to provide support for:

  1. Switching the language
  2. Easy addition of custom translations in any language mutation
  3. Access to underlying i18n instance from i18next library and thus have access to the library’s API

Also, the SDK already provides default translations for the available components.

Integration

The service is made available through the StreamVideo provider. That means that all the child components of this provider can access the StreamI18nContextValue object by using the useI18n context consumer.

The StreamI18nContextValue carries the following properties:

  1. the translator function t - expects to receive a string to translate and returns its translation or the original value, if no translation for the given key and language could be found.
  2. the StreamI18n instance - allows for more control over the service

It is also possible to use StreamI18nProvider without the StreamVideo provider. Again, all the child components of this provider can access the StreamI18nContextValue object by using the useI18n context consumer.

Configuration

What ends up in the StreamI18nContextValue depends on what configuration parameters we provide to the StreamI18nProvider. These are:

type StreamI18nProviderProps = {
  i18nInstance?: StreamI18n;
  language?: string;
  translationsOverrides?: TranslationsMap;
};

StreamVideo internally forwards these parameters to StreamI18nProvider.

In the following sections, we will look more into these individual configuration parameters.

Custom translations

In case you would like to add to or change the default translations, you can use the translationsOverrides prop. This should be an object that will match the type TranslationsMap.

type TranslationsMap = Record<TranslationLanguage, TranslationSheet>;

type TranslationLanguage = keyof typeof defaultTranslations | string;

type TranslationSheet = typeof defaultTranslations.en | Record<string, string>;

The translations are merged with the SDK’s defaults. That means that the defaults are overridden or new keys are added to the translation sheets.

const translations = {
  en: {
    // ...
    terminate: "terminate",
    // ...
  },
  de: {
    // ...
    terminate: "beended",
    // ...
  },
  // ...
};

const App = () => {
  // ...
  return (
    <StreamVideo client={client} translationsOverrides={translations}>
      // ...
    </StreamVideo>
  );
};

Provide your own instance of StreamI18n

You may want to initialize the service somewhere else and pass the instance through the prop i18nInstance. If an instance of StreamI18n is provided, it will be forwarded to the context without any changes.

type CreateI18nParams = {
  language?: string;
  translationsOverrides?: TranslationsMap;
};

const useCreateI18n = ({
  language,
  translationsOverrides,
}: CreateI18nParams) => {
  const i18nRef = useRef(
    new StreamI18n({ currentLanguage: language, translationsOverrides }),
  );

  useEffect(() => {
    const i18n = i18nRef.current;
    if (i18n.isInitialized && language && i18n?.currentLanguage !== language) {
      i18n.changeLanguage(language);
    } else if (!i18n.isInitialized) {
      // sets the default language
      if (!language) i18n.changeLanguage();
      i18n.init();
    }
  }, [language, translationsOverrides]);

  return i18n;
};

const App = () => {
  const i18n = useCreateI18n();

  return (
    <StreamVideo client={client} i18nInstance={i18n}>
      ...
    </StreamVideo>
  );
};

Language

You can set the current language for the translation service with language prop. This should be a language code (for example en, de etc.) that matches a key in translationsOverrides or is among the SDK’s default language mutations which are specified by the type TranslationLanguage.

const App = () => {
  /*  a hook that keeps track of the current language in your app  */
  const { language, setLanguage } = useLanguage();
  // ...
  return (
    <StreamVideo
      client={client}
      language={language}
      translationsOverrides={translations}
    >
      {/*...*/}
    </StreamVideo>
  );
};

Translation function

This is the central feature of the service. The function is passed a string we want to translate and returns its translation. If the translated key is not found, then the returned value is the original string. We rely on the translation function provided by the library i18next. This function is exposed on StreamI18n object as well as in the StreamI18nContextValue.

Accessing the translation function

You can access the translation function in any child component of StreamVideo resp. StreamI18nProvider through the context consumer useI18n:

import { useI18n } from "@stream-io/video-react-sdk";

const CustomButton = () => {
  const { t } = useI18n();

  return <button>{t("Submit")}</button>;
};

Final recommendations

As the translation service is based on i18next which i18n instance is made available through StreamI18n, we encourage you to consult the library’s documentation in order to learn about:

© Getstream.io, Inc. All Rights Reserved.