Multilingual Support
Ekoo supports multilingual audio content, allowing you to serve audio in the right language based on your visitor's locale.
How It Works
When you set the data-ekoo-locale attribute on a widget, Ekoo filters audio content to show only tracks tagged with that locale. The attribute has three behaviours: omitted or empty, every published audio is served; set to auto, the browser's language is used; set to a tag Ekoo does not know, no audio is served.
Locale Attribute
Set the locale directly on the widget element:
1<script src="https://app.ekoo.co/widgets/widget-4.0.0-standalone.js"</script>23<ekoo-widget4 data-ekoo="YOUR_WEBSITE_ID"5 data-ekoo-product-id="YOUR_PRODUCT_ID"6 data-ekoo-locale="fr"7></ekoo-widget>1<ekoo-widget2 data-ekoo="YOUR_WEBSITE_ID"3 data-ekoo-product-id="YOUR_PRODUCT_ID"4 data-ekoo-locale="en"5></ekoo-widget>Supported Locale Values
Ekoo uses its own locale codes
Ekoo locale codes may differ from standard ISO/BCP47 codes. For example: Chinese Simplified is cn (not zh-Hans), Japanese is jp (not ja), Korean is kr (not ko). See the Locale Mapping section below if your site uses standard codes.
| Value | Language |
|---|---|
fr | French |
en | English |
es | Spanish |
de | German |
da | Danish |
sv | Swedish |
fi | Finnish |
no | Norwegian |
it | Italian |
nl | Dutch |
pt | Portuguese |
ar | Arabic |
uk | UK |
bg | BG |
ru | Russian |
pl | Polish |
tr | Turkish |
zh-Hans | Chinese (Simplified) |
zh-Hant | Chinese (Traditional) |
yue | Chinese (Hong Kong) |
ja | Japanese |
ko | Korean |
Auto Detection
With data-ekoo-locale="auto", the widget sends the browser's full navigator.language tag, such as zh-Hant-HK, and Ekoo resolves it one subtag at a time. A tag Ekoo cannot resolve serves no audio rather than audio in another language. Omitting the attribute does not enable detection: it disables filtering.
1<ekoo-widget2 data-ekoo="YOUR_WEBSITE_ID"3 data-ekoo-product-id="YOUR_PRODUCT_ID"4 data-ekoo-locale="auto"5></ekoo-widget>No filtering (all languages)
By omitting the data-ekoo-locale attribute, all published audios for the product will be accessible regardless of locale:
1<ekoo-widget2 data-ekoo="YOUR_WEBSITE_ID"3 data-ekoo-product-id="YOUR_PRODUCT_ID"4></ekoo-widget>JavaScript Configuration
The locale can also be set via window.ekooOptions. The locale goes inside the widgets array (not as a top-level property):
1// window.ekooOptions sets the locale for programmatic widget creation2window.ekooOptions = {3 websiteId: "YOUR_WEBSITE_ID",4 widgets: [5 {6 nodeId: "my-container",7 productId: "my-product",8 locale: "fr"9 }10 ]11};Setting Locale Dynamically
You can change the locale at runtime by updating the attribute and reloading the widget:
1const widget = document.querySelector('[data-ekoo]');2widget.setAttribute('data-ekoo-locale', getUserLocale());3window.ekooReload();React Example
In a React application, you can pass the locale as a prop and trigger a reload when it changes:
1import { useEffect } from 'react';23interface EkooWidgetProps {4 websiteId: string;5 productId: string;6 locale?: string;7}89export function EkooWidget({ websiteId, productId, locale }: EkooWidgetProps) {10 useEffect(() => {11 window.ekooReload();12 }, [locale]);1314 return (15 <ekoo-widget16 data-ekoo={websiteId}17 data-ekoo-product-id={productId}18 data-ekoo-locale={locale}19 ></ekoo-widget>20 );21}Locale Mapping
If your site uses standard BCP47 or ISO language codes (e.g., zh-Hans, ja, ko), you may need a mapping script to convert them to Ekoo locale codes. Add this script before the Ekoo widget script:
1<script>2// Locale mapping: your site's language tag → Ekoo code3// Add this BEFORE the Ekoo widget script4(function() {5 var lookup = {6 'fr': 'fr',7 'fr': 'fr',8 'en': 'en',9 'en': 'en',10 'es': 'es',11 'es': 'es',12 'de': 'de',13 'de': 'de',14 'da': 'da',15 'da': 'da',16 'dk': 'da',17 'sv': 'sv',18 'sv': 'sv',19 'fi': 'fi',20 'fi': 'fi',21 'no': 'no',22 'no': 'no',23 'nb': 'no',24 'nn': 'no',25 'it': 'it',26 'it': 'it',27 'nl': 'nl',28 'nl': 'nl',29 'vl': 'nl',30 'pt': 'pt',31 'pt': 'pt',32 'ar': 'ar',33 'ar': 'ar',34 'uk': 'uk',35 'uk': 'uk',36 'bg': 'bg',37 'bg': 'bg',38 'ru': 'ru',39 'ru': 'ru',40 'pl': 'pl',41 'pl': 'pl',42 'tr': 'tr',43 'tr': 'tr',44 'cn': 'zh-Hans',45 'zh-hans': 'zh-Hans',46 'cn': 'zh-Hans',47 'zh': 'zh-Hans',48 'zh-cn': 'zh-Hans',49 'tw': 'zh-Hant',50 'zh-hant': 'zh-Hant',51 'tw': 'zh-Hant',52 'zh-tw': 'zh-Hant',53 'zh-hk': 'zh-Hant',54 'zh-mo': 'zh-Hant',55 'hk': 'yue',56 'yue': 'yue',57 'hk': 'yue',58 'yue-hk': 'yue',59 'jp': 'ja',60 'ja': 'ja',61 'jp': 'ja',62 'kr': 'ko',63 'ko': 'ko',64 'kr': 'ko'65 };6667 window.ekooGetLocale = function() {68 var lang = (document.documentElement.getAttribute('lang') || '').trim().toLowerCase();6970 // No lang attribute: no locale filter, the widget serves every audio.71 if (!lang) return '';7273 // Drop one subtag at a time from the right, so zh-Hant-HK is tried before74 // zh-Hant and zh, and the script subtag is never skipped over.75 var subtags = lang.split(/[-_]/);76 for (var n = subtags.length; n >= 1; n--) {77 var candidate = subtags.slice(0, n).join('-');78 if (lookup[candidate]) return lookup[candidate];79 }8081 // Unknown language: pass the tag through unchanged. The server answers with82 // an empty catalogue, which is the honest result. Never substitute another83 // language here.84 return lang;85 };86})();87</script>Then use the helper function to set the locale dynamically:
1<div2 data-ekoo="YOUR_WEBSITE_ID"3 data-ekoo-product-id="YOUR_PRODUCT_ID"4></div>56<script>7 // After DOM is ready, set the locale from the mapping8 var widget = document.querySelector('[data-ekoo]');9 if (widget && window.ekooGetLocale) {10 widget.setAttribute('data-ekoo-locale', window.ekooGetLocale());11 }12</script>Tag your audio content
UI language is not affected