---
title: Internationalization
sidebar_label: I18N
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

Vime supports multiple languages out of the box, and includes an [english translation][eng-translation]
by default. We can extend the player with new languages and change between them dynamically very easily.
The following [player properties](../components/core/player#properties) are part of our i18n kit:

- `language`: The current language of the player, preferably an [ISO 639-1 code][iso-639-1]. Changing
  this will update the `i18n` property, and the language being set must be available in `languages`.
- `languages`: List of available languages. This is automatically updated based on the keys in `translations`.
- `translations`: A dictionary containing each language as the key, and [translation map][translation-map]
  as the value. We'll discuss how you can extend this below.
- `i18n`: The [translation map][translation-map] for the current `language`.

The only properties you will directly set is `language` and `translations`, the rest are readonly
and updated automatically. Let's first look at how we can create new translations...

:::tip

- If you're not using TypeScript then refer to the [english translation][eng-translation] as a
  reference on how to create a new translation.
- Video.js has an awesome collection of [languages][videojs-lang] available for you to use as a
  reference.
  :::

```ts title="player-lang.ts"
// This is exported from all packages (react/vue/svelte/angular).
import { Translation } from '@vime/core';

// Turkish translation.
export const tr: Translation = {
  play: 'Oynat',
  pause: 'Duraklat',
  // ...
  randomWord: 'Rastgele kelime',
};

// Russian translation.
export const ru: Translation = {
  play: 'Воспроизвести',
  pause: 'Приостановить',
  // ...
  randomWord: 'Cлучайное слово',
};
```

Once we have our translations ready we can pass them in through the `translations` property or
the `extendLanguage` method on the player. The difference is that `translations` will overwrite
all existing translations, and `extendLanguage` will only extend them. Let' see how we can use them...

<Tabs
groupId="framework"
defaultValue="html"
values={[
{ label: 'HTML', value: 'html' },
{ label: 'React', value: 'react' },
{ label: 'Vue', value: 'vue' },
{ label: 'Svelte', value: 'svelte' },
{ label: 'Stencil', value: 'stencil' },
{ label: 'Angular', value: 'angular' }
]}>

<TabItem value="html">

```html {9-13,16-18} title="player.html"
<vm-player language="tr">
  <!-- ... -->
</vm-player>

<script>
  const player = document.querySelector('vm-player');

  // Option 1 using the `translations` property.
  player.translations = {
    tr: {
      // ...
    },
  };

  // Option 2 using the `extendLanguage` method.
  player.extendLanguage('tr', {
    // ...
  });
</script>
```

</TabItem>

<TabItem value="react">

```tsx {10-11,18} title="Player.tsx"
import React, { useRef } from 'react';
import { Player } from '@vime/react';
import { tr, ru } from './player-lang';

function Player() {
  const player = useRef<HTMLVmPlayerElement>(null);

  const onReady = () => {
    // Option 2 using the `extendLanguage` method.
    player.current.extendLanguage('tr', tr);
    player.current.extendLanguage('ru', ru);
  };

  return (
    {/* Option 1 using the `translations` property. */}
    <Player
      language="tr"
      translations={{ tr, ru }}
      ref={player}
      onVmReady={onReady}
    >
      {/* ... */}
    </Player>
  );
}
```

</TabItem>

<TabItem value="vue">

```html {5,22,27-28} title="Player.vue"
<template>
  <Player
    language="tr"
    ref="player"
    :translations="translations"
    @vReady="onReady"
  >
    <!-- ... -->
  </Player>
</template>

<script>
  import { Player } from '@vime/vue';
  import { tr, ru } from './player-lang';

  export default {
    components: {
      Player,
    },
    data: {
      // Option 1 using the `translations` property.
      translations: { tr, ru },
    },
    methods: {
      onReady() {
        // Option 2 using the `extendLanguage` method.
        this.$refs.player.extendLanguage('tr', tr);
        this.$refs.player.extendLanguage('ru', ru);
      },
    },
  };
</script>
```

</TabItem>

<TabItem value="svelte">

```html {4,19-20} title="Player.svelte"
<!-- Option 1 using the `translations` property. -->
<Player
  language="tr"
  translations="{{"
  tr,
  ru
  }}
  on:vReady="{onReady}"
  ref="{player}"
>
  <!-- ... -->
</Player>

<script lang="ts">
  import { Player } from '@vime/svelte';
  import { tr, ru } from './player-lang';

  let player: Player;

  const onReady = () => {
    // Option 2 using the `extendLanguage` method.
    player.extendLanguage('tr', tr);
    player.extendLanguage('ru', ru);
  };
</script>
```

</TabItem>

<TabItem value="stencil">

```tsx {8-9,17} title="player.tsx"
import { tr, ru } from './player-lang';

class Player {
  private player!: HTMLVmPlayerElement;

  private onReady() {
    // Option 2 using the `extendLanguage` method.
    this.player.extendLanguage('tr', tr);
    this.player.extendLanguage('ru', ru);
  }

  render() {
    return (
      {/* Option 1 using the `translations` property. */}
      <vm-player
        language="tr"
        translations={{ tr, ru }}
        onVmReady={this.onReady.bind(this)}
        ref={(el) => { this.player = el; }}
      >
        {/* ... */}
      </vm-player>
    );
  }
}
```

</TabItem>

<TabItem value="angular">

```html {4} title="player.html"
<vm-player
  #player
  language="tr"
  [translations]="translations"
  (vReady)="onReady"
>
  <!-- ... -->
</vm-player>
```

```ts {9,13-14} title="player.ts"
import { ViewChild } from '@angular/core';
import { Player } from '@vime/angular';
import { tr, ru } from './player-lang';

class Player {
  @ViewChild('player') player!: Player;

  // Option 1 using the `translations` property.
  translations = { tr, ru };

  onReady() {
    // Option 2 using the `extendLanguage` method.
    player.nativeElement.extendLanguage('tr', tr);
    player.nativeElement.extendLanguage('ru', ru);
  }
}
```

</TabItem>
    
</Tabs>

Now we can simply change the `language` property and all the text inside the player will update
accordingly. If you're creating your own UI components then make sure to not use static text, instead
use the `i18n` property such as `{i18n.play}` so they can also update when the language changes.

[videojs-lang]: https://github.com/videojs/video.js/tree/main/lang
[iso-639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
[eng-translation]: https://github.com/vime-js/vime/blob/src/components/core/player/lang/en.ts
[translation-map]: https://github.com/vime-js/vime/blob/src/components/core/player/lang/Translation.ts
