Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Media Chrome supports multiple languages for its UI components. By default, it u
## Available Languages
Currently, the supported languages are:

- **Chinese (Simplified)** (`zh-CN`)
- **Chinese (Traditional)** (`zh-TW`)
- **English** (default)
- **French** (`fr`)
- **German** (`de`)
Expand Down Expand Up @@ -37,22 +39,50 @@ import "media-chrome/lang/pt.js";
Again, replace `pt.js` with the desired language code.

## How Language Selection Works
Media Chrome automatically detects the user's preferred language based on their browser settings. If the corresponding language file has been imported, the UI will switch to that language.
Media Chrome automatically detects the user's preferred language based on their browser settings. If the corresponding language file has been imported, the UI will switch to that language.

> **Note:** When using HTML, make sure the language file `<script>` tag is loaded **before** the main Media Chrome script so the translations are registered before the components initialize.

If the user’s preferred language is not available, the UI will fall back to English.

## Manually Setting the Language

You can also override the language explicitly by setting the `lang` attribute on the `<media-controller>` element after the language file has been loaded:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/media-chrome@4/dist/lang/es.js"></script>

<media-controller lang="es">
...
</media-controller>
```

Or dynamically via JavaScript after the language module is imported:

```js
import "media-chrome/lang/es.js";

const controller = document.querySelector("media-controller");
controller.setAttribute("lang", "es");
```

This is useful when you want to set the language programmatically regardless of the user’s browser settings.


## Adding a New Language
If you want to add support for a new language, you can create your own language file by extending an existing one, such as `es.js`. Here’s how:

1. Copy the contents of an existing language file (e.g., `es.js`).
2. Modify the translations to match your desired language.
3. Save it as a new file, e.g., `de.js` for German.
3. Save it as a new file, e.g., `it.js` for Italian.
4. Import it into your project using:

```js
import "./path-to-your-lang/de.js";
import "./path-to-your-lang/it.js";
```

5. Ensure the browser can detect and apply the language based on user preferences.

## Contributing a Language to the Library

Want to share your translation? Create a fork of the [muxinc/media-chrome](https://github.com/muxinc/media-chrome) repository, add your language file to `src/js/lang/`, and open a [Pull Request](https://github.com/muxinc/media-chrome/pulls).
69 changes: 54 additions & 15 deletions examples/vanilla/internationalization.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
<meta name="viewport" content="width=device-width">
<title>Media Chrome Advanced Video Usage Example</title>
<script type="module" src="https://cdn.jsdelivr.net/npm/hls-video-element@1.1/+esm"></script>
<script type="module" src="../../dist/index.js"></script>
<script type="module" src="../../dist/menu/index.js"></script>
<script type="module" src="../../dist/lang/es.js"></script>
<script type="module" src="../../dist/lang/pt.js"></script>
<script type="module" src="../../dist/lang/fr.js"></script>
<script type="module" src="../../dist/lang/zh-CN.js"></script>
<script type="module" src="../../dist/lang/zh-TW.js"></script>
<script type="module" src="../../dist/lang/es.js"></script>
<script type="module" src="../../dist/lang/de.js"></script>
<script type="module" src="../../dist/lang/fr.js"></script>
<script type="module" src="../../dist/lang/pt.js"></script>
<script type="module" src="../../dist/index.js"></script>
<script type="module" src="../../dist/menu/index.js"></script>
<style>
/* Hide custom elements that are not defined yet */
:not(:defined) {
Expand Down Expand Up @@ -62,7 +63,7 @@ <h1>Media Chrome - Internationalization Usage Example</h1>

<media-controller
id="mc"
lang='en'
Comment thread
cursor[bot] marked this conversation as resolved.
lang="en"
defaultsubtitles
keyboardforwardseekoffset="15"
keyboardbackwardseekoffset="5"
Expand Down Expand Up @@ -120,24 +121,62 @@ <h1>Media Chrome - Internationalization Usage Example</h1>
</media-controller>
</main>

<p id="browser-lang-info"></p>
<p id="set-lang-info"></p>
<hr/>
<p>
<button onclick='setLang("en")'>Switch to English</button>
<button onclick='setLang("es")'>Switch to Spanish</button>
<button onclick='setLang("fr")'>Switch to French</button>
<button onclick='setLang("pt")'>Switch to Portuguese</button>
<button onclick='setLang("zh-CN")'>Switch to Chinese (Simplified)</button>
<button onclick='setLang("zh-TW")'>Switch to Chinese (Traditional)</button>
<label for="lang-select">Switch Language:</label>
<select id="lang-select" onchange='setLang(this.value)'>
<option value="zh-CN">Chinese (Simplified)</option>
<option value="zh-TW">Chinese (Traditional)</option>
<option value="en">English</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="pt">Portuguese</option>
<option value="es">Spanish</option>
</select>
</p>

<script>
const browserLang = navigator.language;
const displayName = new Intl.DisplayNames([browserLang], { type: 'language' }).of(browserLang);
document.getElementById('browser-lang-info').innerHTML =
`Browser language detected: <strong>[${browserLang}]</strong> - (${displayName})`;

function getAvailableLangs() {
return Array.from(document.getElementById('lang-select').options)
.map(o => o.value)
.filter(v => v !== '');
}

function resolveLang(lang, available) {
if (available.includes(lang)) return lang;
const base = lang.split('-')[0];
return available.find(l => l === base || l.startsWith(base + '-')) ?? 'en';
}

function updateSetLangInfo() {
const active = document.getElementById('mc').resolvedLang ?? 'en';
const setDisplayName = new Intl.DisplayNames([active], { type: 'language' }).of(active);
document.getElementById('set-lang-info').innerHTML =
`Language set: <strong>[${active}]</strong> - (${setDisplayName})`;
document.documentElement.lang = active;
}
Comment thread
cursor[bot] marked this conversation as resolved.

function setLang(lang) {
const mediaController = document.getElementById('mc');
mediaController.setAttribute('lang', lang);
document.getElementById('mc').setAttribute('lang', lang);
document.getElementById('lang-select').value = lang;
updateSetLangInfo();
}

customElements.whenDefined('media-controller').then(() => {
const lang = resolveLang(browserLang, getAvailableLangs());
setLang(lang);
});
</script>

<div class="examples">
<a href="./">View more examples</a>
</div>
</body>
</html>
</html>
6 changes: 5 additions & 1 deletion src/js/media-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
} from './utils/element-utils.js';
import { createMediaStore, MediaStore } from './media-store/media-store.js';
import { CustomElement } from './utils/CustomElement.js';
import { setLanguage } from './utils/i18n.js';
import { setLanguage, getResolvedLanguage } from './utils/i18n.js';

const ButtonPressedKeys = [
'ArrowLeft',
Expand Down Expand Up @@ -317,6 +317,10 @@ class MediaController extends MediaContainer {
setBooleanAttr(this, Attributes.NO_DEFAULT_STORE, value);
}

get resolvedLang(): string {
return getResolvedLanguage();
}

attributeChangedCallback(
attrName: string,
oldValue: string | null,
Expand Down
7 changes: 7 additions & 0 deletions src/js/utils/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ const resolveTranslation = (key: TranslateKeys): string => {
);
};

export const getResolvedLanguage = (): string => {
const [base] = currentLang.split('-');
if (translations[currentLang]) return currentLang;
if (translations[base]) return base;
return 'en';
};

export const t = (
key: TranslateKeys,
vars: Record<string, string | number> = {}
Expand Down
Loading