Korbs revised this gist . Go to revision
2 files changed, 9 insertions
README.md(file created)
@@ -0,0 +1,8 @@ | |||
1 | + | # i18n in Vanilla JavaScript | |
2 | + | ||
3 | + | In your HTML elements, use the `data-i18n` attribute to apply a translation key: | |
4 | + | ```html | |
5 | + | <p data-i18n="example"></p> | |
6 | + | ``` | |
7 | + | ||
8 | + | You can also use the `i18n.dist.js` file in production, as it's 36% smaller in file size compared to `i18n.js`. |
i18n.dist.js(file created)
@@ -0,0 +1 @@ | |||
1 | + | const e=availableLocales[0];let a=window.navigator.language;const t=new URLSearchParams(window.location.search).get("lang");t&&availableLocales.includes(t)&&(a=t);let l=e;availableLocales.includes(a)&&(l=a);const c=document.querySelectorAll("[data-i18n]"),n=locales[l];c.forEach((e=>{let a=e.getAttribute("data-i18n").split(".").reduce(((e,a)=>e?e[a]:null),n);const t=a.match(/{(.*?)}/g);t&&t.forEach((t=>{Object.entries(e.dataset).filter((([e,l])=>{if(`{${e}}`===t)try{a=a.replace(`${t}`,new Function(`return (${l})`)())}catch(e){a=a.replace(`${t}`,l)}}))})),e.innerHTML=a}));document.querySelector("html").setAttribute("lang",l); |
Korbs revised this gist . Go to revision
2 files changed, 65 insertions
i18n.js(file created)
@@ -0,0 +1,27 @@ | |||
1 | + | const defaultLanguage = availableLocales[0] | |
2 | + | let language = (window.navigator.language) | |
3 | + | const urlParams = new URLSearchParams(window.location.search) | |
4 | + | const langFromUrl = urlParams.get('lang') | |
5 | + | if (langFromUrl && availableLocales.includes(langFromUrl)) {language = langFromUrl} | |
6 | + | let pageLanguage = defaultLanguage | |
7 | + | if (availableLocales.includes(language)) {pageLanguage = language} | |
8 | + | const elements = document.querySelectorAll('[data-i18n]') | |
9 | + | const json = locales[pageLanguage] | |
10 | + | elements.forEach((element) => { | |
11 | + | const key = element.getAttribute('data-i18n') | |
12 | + | let text = key.split('.').reduce((obj, i) => (obj ? obj[i] : null), json) | |
13 | + | const variables = text.match(/{(.*?)}/g) | |
14 | + | if (variables) { | |
15 | + | variables.forEach((variable) => { | |
16 | + | Object.entries(element.dataset).filter(([key, value]) => { | |
17 | + | if (`{${key}}` === variable) { | |
18 | + | try {text = text.replace(`${variable}`, new Function(`return (${value})`)())} | |
19 | + | catch (error) {text = text.replace(`${variable}`, value)} | |
20 | + | } | |
21 | + | }) | |
22 | + | }) | |
23 | + | } | |
24 | + | element.innerHTML = text | |
25 | + | }) | |
26 | + | const htmlElement = document.querySelector('html') | |
27 | + | htmlElement.setAttribute('lang', pageLanguage) |
index.html(file created)
@@ -0,0 +1,38 @@ | |||
1 | + | <h2 data-i18n="page-heading"></h2> | |
2 | + | <p data-i18n="message"></p> | |
3 | + | <a data-i18n="links.source" href="#"></a> | |
4 | + | ||
5 | + | <script> | |
6 | + | const availableLocales = ['en', 'jp'] | |
7 | + | const locales = { | |
8 | + | en: { | |
9 | + | "page-heading": "i18n in Vanilla JavaScript", | |
10 | + | "message": "This is a sample text.", | |
11 | + | "links": { | |
12 | + | "source": "View Source Code" | |
13 | + | } | |
14 | + | }, | |
15 | + | jp: { | |
16 | + | "page-heading": "バニラ JavaScriptでi18n", | |
17 | + | "message": "サンプルテキストです.", | |
18 | + | "links": { | |
19 | + | "source": "ソースコードを見る" | |
20 | + | } | |
21 | + | } | |
22 | + | } | |
23 | + | </script> | |
24 | + | <script src="./i18n.js"></script> | |
25 | + | ||
26 | + | ||
27 | + | <!-- This style tag is here for demo purposes, it is not needed at all for i18n to function --> | |
28 | + | <style> | |
29 | + | body { | |
30 | + | margin: 24px; | |
31 | + | background: #141414; | |
32 | + | color: white; | |
33 | + | font-family: arial, sans-serif; | |
34 | + | } | |
35 | + | a { | |
36 | + | color: white; | |
37 | + | } | |
38 | + | </style> |