Korbs revised this gist 1 week ago. Go to revision
1 file changed, 1 insertion, 1 deletion
README.md
| @@ -1,4 +1,4 @@ | |||
| 1 | - | # i18n in Vanilla JavaScript | |
| 1 | + | # i18n in Vanilla JavaScript - [[Playground](https://playpen.sudovanilla.org/#H4sIAAAAAAAAA51U3YrbRhS%2B91OcKsvuTJG1zZKLYlsOoT%2BUsqUhm%2BbGGHwsHUuzGc%2BoM6N1jNHFWlBS9qb0pvQFGkrpVehFoX0a3fQxysiO7d0mLVQCoZnz933fnDOD%2FAxSdNgV9z9UcVBgRt2cMBUqC4aD0%2Fxs2BkUhx5zshYz8sZi2BngoU0K9dxGVpcmoQByQ7M4uOc9cdjpDN7rduFx6UAoWOrSgKMXDrrdYWdgEyMKN%2BwAACRaWQd4hULiVNK5TlCShRhGJ6ROQji5LE7GB55y57Bqd%2F1Dqnew8s9tYj0IPGCP5BkqISXC53iFFy2MILwd%2BYZwD4KnubAgLCBYnBeSWgrR3YBWheAugta0laYHwTNBC7hol%2FCRTim45VztVtU%2B%2BWXxn6ya%2Brumvmnqnw%2F4NNevPNl%2FodWsf2vq1039Q1P%2F0tTfNOtfm%2FXvTf2yuX7VXP%2F4%2F%2Fg16z%2Bb%2Bg%2BfZ%2F3a%2F9TfNuvv%2F%2FrpplnfvJNqZ%2FMdnL7ph03PtKpbt%2FR6Y%2Bb1z8kQzLSBlOYaitIU2pINQThvVdqBIkopBXSAUrau7YE7DbNSJU5ote08n3bTeFOdLg84zdFkQvXg7EHxor%2FbnWLyPDO6VGkP7t1%2F4N%2B9MdFSmx4scuFovzvTynVnOBdy2QM0AmUIFpXtWjJi1u%2FsqeNB%2BX%2FmaoXZwN3o0jL6WFgHm4O%2BPUub6aD47iSNPhj3JTnAeCFUqheRwiuRodMmkqiyEjPqb2JdrGgBXz05vyA0Sf4YDc4t20b5sfMyRrY18igjxwKfIeB9d3x8t2wkVCLLlCxz%2FPiYYex4C0PG1H%2B3L3pfGSPfQkriVCflnJSLvi7JLC9IUuK0eSQlC0a7m2gc8FDF25thJMf9JJpp8wkmOWMUD1cb%2FuQxP3LOiGnpiAW78IBHtpDCsSAKeGQoLRNijFGIPB7SQxrhuKdKKXmo%2BE4rjObokpydrlj0%2FkNenWatDm5f2cXD1ZfTS0pcRMoZQZZR5ItacjyaCenIMMZGFMoxj4crMWOT1dGKqmoSx7HjzixXGGNkqJCYEJscrVw1Cf0hfbptajYx5EqjgB2tZMUnnHFeJS0u4m8LlryqOK84DykSSpH57OkX5zFWnPffrjQLcjeXXqFb2rUHH0re30%2Fv32IH%2FmNaBgAA)] | |
| 2 | 2 | ||
| 3 | 3 | In your HTML elements, use the `data-i18n` attribute to apply a translation key: | |
| 4 | 4 | ```html | |
Korbs revised this gist 7 months ago. 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 7 months ago. 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> | |