├── .npmignore
├── static
├── vue.png
├── react.png
├── angular.png
└── browserify.png
├── .github
└── FUNDING.yml
├── src
├── main.js
└── LanguageLocator.js
├── package.json
├── LICENSE
├── .gitignore
└── README.md
/.npmignore:
--------------------------------------------------------------------------------
1 | *.tgz
2 | static
--------------------------------------------------------------------------------
/static/vue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atapas/i18n-js-npm/HEAD/static/vue.png
--------------------------------------------------------------------------------
/static/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atapas/i18n-js-npm/HEAD/static/react.png
--------------------------------------------------------------------------------
/static/angular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atapas/i18n-js-npm/HEAD/static/angular.png
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [atapas]
4 |
--------------------------------------------------------------------------------
/static/browserify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atapas/i18n-js-npm/HEAD/static/browserify.png
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Created on Tue May 12 2020
4 | *
5 | * Copyright (c) 2020 https://tapasadhikary.com
6 | */
7 |
8 | module.exports = require('./LanguageLocator.js');
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "i18n-web",
3 | "version": "0.0.4",
4 | "description": "A simple tool helps in externalizing the strings in a JavaScript Application. It has the additional capability of parameterizing the strings.",
5 | "main": "src/main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/atapas/i18n-js-npm.git"
12 | },
13 | "keywords": [
14 | "intl",
15 | "i18n",
16 | "internationalization",
17 | "locale",
18 | "translate",
19 | "translation",
20 | "javascript",
21 | "react",
22 | "angular",
23 | "vue",
24 | "web"
25 | ],
26 | "author": "Tapas Adhikary",
27 | "license": "MIT",
28 | "bugs": {
29 | "url": "https://github.com/atapas/i18n-js-npm/issues"
30 | },
31 | "homepage": "https://github.com/atapas/i18n-js-npm#readme"
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Tapas Adhikary
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/LanguageLocator.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Created on Tue May 12 2020
3 | *
4 | * Copyright (c) 2020 https://tapasadhikary.com
5 | */
6 |
7 |
8 | import * as Langs from '../../../i18n/index.js';
9 |
10 |
11 | let clientPrimaryLang = navigator.languages[0];
12 |
13 | let matchedLang = clientPrimaryLang.indexOf('-') > 0 ?
14 | clientPrimaryLang.substring(0, clientPrimaryLang.indexOf('-')) :
15 | clientPrimaryLang;
16 |
17 | console.log(matchedLang);
18 |
19 | const replaceParams = (replaced, ...params) => {
20 | params.forEach((item, index) => {
21 | let match = new RegExp(`\\{${index}\\}`);
22 | replaced = replaced.replace(match, item);
23 | });
24 | return replaced;
25 | }
26 |
27 | const i18n = (key, ...params) => {
28 | console.log(params);
29 | let value = '';
30 |
31 | if (Langs[matchedLang]) {
32 | if (key.indexOf('.') > 0) {
33 | // Support nested key
34 | value = Langs[matchedLang][key.split('.')[0]][key.split('.')[1]];
35 | } else {
36 | value = Langs[matchedLang][key];
37 | }
38 | } else {
39 | // If the user preferred language is not supported,
40 | // fallback to english('en')
41 | if (key.indexOf('.') > 0) {
42 | // Support nested key
43 | value = Langs['en'][key.split('.')[0]][key.split('.')[1]];
44 | } else {
45 | value = Langs['en'][key];
46 | }
47 | }
48 |
49 | let replaced = value;
50 | if (params && params.length > 0) {
51 | // replace {0}, {1} etc with param 1 and param 2
52 | replaced = replaceParams(replaced, ...params);
53 | }
54 | return replaced;
55 | };
56 |
57 | export default i18n;
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # i18n-web
2 |
3 | `i18n-web` is a simple tool helps in externalizing the strings in a JavaScript based Application such that, Internationalization(i18n) can be achieved easily. It has the additional capability of parameterizing the strings to get the dynamic content Internationalized.
4 |
5 | # Install
6 |
7 | - Using yarn: `yarn add i18n-web`
8 | - Using npm: `npm install i18n-web`
9 |
10 | # What is String Externalization?
11 | String Externalization means, instead of writing the user(or customer) facing strings in source files(.html, .js, .java etc), we keep them in an external file like .properties, .json etc and load from there. This is to help Internationalization (i18n).
12 |
13 | # What is Internationalization (i18n)?
14 | In Software, Internationalization (i18n) is the process to support various local languages like, English(en), Spanish(es), German(de) etc.
15 |
16 | All the browsers come with the in-built support of languages which can be used to identify the local language to support for the application.
17 |
18 | # How String Externalization help in Internationalization (i18n) of the Web Applications?
19 | A Web Application may have the need of supporting multiple languages based on the targeted users. If the Application Strings are Externalized outside of the source files, it is easy and flexible to support i18n.
20 |
21 | Lets consider, all the application strings are in a file called `en.json` and this file can be loaded into the application to retrieve the strings when the app is running in English Language.
22 |
23 | ```js
24 | {
25 | 'username': 'User Name',
26 | 'password': 'Password',
27 | 'hasBlog': '{0} has a blog named, {1}. This is on {2}.'
28 | }
29 | ```
30 |
31 | Now there could be equivalent `es.json` file which can be loaded into the application when browser supported language is Spanish instead of English.
32 |
33 | ```js
34 | {
35 | 'username': 'Nombre de usuario',
36 | 'password': 'Contraseña',
37 | 'hasBlog': '{0} tiene un blog llamado {1}. Esto está en {2}.'
38 | }
39 | ```
40 |
41 | # i18n-web Usage
42 |
43 | ## Basic Setup and Structure
44 |
45 | The tool `i18n-web` helps in externalizing the string and thus, internationalizing your web app with few quick and easy steps.
46 |
47 | - Create a folder called `i18n` at the same level of `node_modules` folder of your app.
48 | - Create `en.js`, `es.js`, `de.js` etc file to contain your application specific strings externalized. You must add all required language .js files that your app would support.
49 |
50 | Here is an example of the en.js and es.js file.
51 |
52 | ```js
53 | // en.js
54 | const en = {
55 | 'username': 'User Name',
56 | 'password': 'Password',
57 | 'hasBlog': '{0} has a blog named, {1}. This is on {2}.'
58 | }
59 |
60 | export { en };
61 | ```
62 |
63 | ```js
64 | // es.js
65 | const es = {
66 | 'username': 'Nombre de usuario',
67 | 'password': 'Contraseña',
68 | 'hasBlog': '{0} tiene un blog llamado {1}. Esto está en {2}.'
69 | }
70 |
71 | export { es };
72 | ```
73 |
74 | - Create another file called, `index.js` where you can aggregate the all modules and export together like this:
75 |
76 | ```js
77 | export { en } from './en.js';
78 | export { es } from './es.js';
79 | ```
80 |
81 | Example Directory Structure:
82 |
83 | ```
84 | myapp
85 | └── i18n
86 | └── en.js
87 | └── es.js
88 | └── de.js
89 | └── fr.js
90 | └── index.js
91 | └── node_modules
92 | ```
93 |
94 | ## Using it in UI Code
95 |
96 | - In your UI Code, import it as,
97 |
98 | ```js
99 | import i18n from 'i18n-web';
100 | ```
101 |
102 | - Use it like:
103 |
104 | ```js
105 | // When no parameters. Just Key is passed
106 | console.log(i18n('usename'));
107 |
108 | // Output:
109 |
110 | // 'User Name' for English
111 |
112 | // 'Nombre de usuario' for Spanish
113 |
114 | ```
115 |
116 | ```js
117 | // With parameters.
118 | const params = ['Tapas', 'greenroos', 'JavaScript'];
119 | let hasBlog = i18n('hasBlog', ...params);
120 | console.log(hasBlog);
121 |
122 | // Output:
123 |
124 | // 'Tapas has a blog named, greenroots. This is on JavaScript.' for English and
125 |
126 | // 'Tapas tiene un blog llamado greenroots. Esto está en JavaScript.' for Spanish
127 | ```
128 |
129 | # Tested with
130 |
131 | [
](https://angular.io/)
132 | [
](https://reactjs.org/)
133 | [
](https://vuejs.org/)
134 | [
](http://browserify.org/)
135 |
136 |
137 |
--------------------------------------------------------------------------------