5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/universal-language-detector.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v12.14.0
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "12.14"
4 | cache:
5 | directories:
6 | - node_modules
7 | install:
8 | - yarn install
9 | script:
10 | - yarn run test:once
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | CHANGELOG
2 | ===
3 |
4 | - v2.0.3 - 2020-03-04
5 | - [Bugfix] Localised languages such as fr-FR/en-US where blacklisted when using the "navigator" resolver, which caused the language to be wrongfully detected (i.e: "en-US, fr, en" would return "fr"), now it properly returns "en"
6 | - v2.0.2 - 2020-02-06
7 | - [Bugfix] Use `@unly/iso3166-1` instead of `iso3166-1` in source code (forgot to change this alongside the package.json in v2.0.1)
8 | - v2.0.1 - 2020-02-04
9 | - [Enhancement] Use `@unly/iso3166-1` instead of `iso3166-1` (robustness)
10 | - v2.0.0 - 2020-01-09
11 | - [Release] Release v2 with **breaking API changes**
12 | - Remove all stuff that was related to our internal business logic at Unly (this lib is a port of an internal project and was suffering from internal business logic/needs that shouldn't have been part of the Open Source release, they have been removed)
13 | - [BREAKING] Removed API function `universalLanguagesDetect` (plural), kept only `universalLanguageDetect`
14 | - [BREAKING] Renamed `acceptedLanguages` into `supportedLanguages` to avoid confusion with `accept-language` header
15 | - [BREAKING] Renamed `acceptLanguage` into `acceptLanguageHeader` for clarity
16 | - v1.0.0 - 2019-12-30
17 | - [Release] Release production-ready 1.0.0 version
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Unly
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [](https://codeclimate.com/github/UnlyEd/universal-language-detector/maintainability)
3 | [](https://codeclimate.com/github/UnlyEd/universal-language-detector/test_coverage)
4 | [](https://snyk.io/test/github/UnlyEd/universal-language-detector?targetFile=package.json)
5 | # Universal Language Detector
6 |
7 | > Language detector that works universally (browser + server)
8 | >
9 | > - On the server, will rely on "cookies > accept-language header"
10 | > - On the browser, will rely on "cookies > navigator settings"
11 | >
12 | > Meant to be used with a universal framework, such as Next.js
13 |
14 |
15 | Note that this lib helps resolving the **`language`** (`fr`, `en`, `es`, etc.), **not the locale** (`fr-FR`, `en-US`, etc.)
16 |
17 | _It is not out of scope though, PR are welcome to support universal locale detection._
18 |
19 | ---
20 |
21 |
22 |
23 | * [Demo](#demo)
24 | * [Getting started](#getting-started)
25 | * [Examples](#examples)
26 | * [API](#api)
27 | + [`universalLanguageDetect`](#universallanguagedetect)
28 | * [Contributing](#contributing)
29 | + [Working locally](#working-locally)
30 | + [Test](#test)
31 | + [Versions](#versions)
32 | - [SemVer](#semver)
33 | + [Releasing and publishing](#releasing-and-publishing)
34 | * [Changelog](#changelog)
35 | * [License](#license)
36 | - [Vulnerability disclosure](#vulnerability-disclosure)
37 | - [Contributors and maintainers](#contributors-and-maintainers)
38 | - [**[ABOUT UNLY]**](#about-unly-)
39 |
40 |
41 |
42 | ---
43 |
44 | ## Demo
45 |
46 | [Live demo with the Next.js example](https://universal-language-detector.now.sh/)
47 |
48 | ## Getting started
49 |
50 | ```
51 | yarn install @unly/universal-language-detector
52 | ```
53 |
54 | Use:
55 |
56 | ```
57 | import universalLanguageDetect from '@unly/universal-language-detector';
58 |
59 | OR
60 |
61 | import { universalLanguageDetect } from '@unly/universal-language-detector';
62 | ```
63 |
64 | ## Examples
65 |
66 | See [our example](./examples/with-next) featuring the Next.js framework
67 |
68 | ---
69 |
70 | ## API
71 |
72 | > Extensive API documentation can be found in the [source code documentation](./src/index.ts)
73 | >
74 | > Only the most useful API methods are documented here, the other aren't meant to be used, even though they may be
75 |
76 | ### `universalLanguageDetect`
77 |
78 | > Detects the language used, universally.
79 |
80 | **Parameters:**
81 | - `supportedLanguages`: string[];
82 | - `fallbackLanguage`: string;
83 | - `acceptLanguageHeader?`: string | undefined;
84 | - `serverCookies?`: object | undefined;
85 | - `errorHandler?`: [ErrorHandler](./src/utils/error.ts) | undefined;
86 |
87 | **Example:**
88 | ```js
89 | const lang = universalLanguageDetect({
90 | supportedLanguages: SUPPORTED_LANGUAGES, // Whitelist of supported languages, will be used to filter out languages that aren't supported
91 | fallbackLanguage: FALLBACK_LANG, // Fallback language in case the user's language cannot be resolved
92 | acceptLanguageHeader: get(req, 'headers.accept-language'), // Optional - Accept-language header will be used when resolving the language on the server side
93 | serverCookies: cookies, // Optional - Cookie "i18next" takes precedence over navigator configuration (ex: "i18next: fr"), will only be used on the server side
94 | errorHandler: (error) => { // Optional - Use you own logger here, Sentry, etc.
95 | console.log('Custom error handler:');
96 | console.error(error);
97 | },
98 | });
99 | ```
100 |
101 | ---
102 |
103 | ## Contributing
104 |
105 | We gladly accept PRs, but please open an issue first so we can discuss it beforehand.
106 |
107 | ### Working locally
108 |
109 | ```
110 | yarn start # Shortcut - Runs linter + build + tests in concurrent mode (watch mode)
111 |
112 | OR run each process separately for finer control
113 |
114 | yarn lint
115 | yarn build
116 | yarn test
117 | ```
118 |
119 | ### Test
120 |
121 | ```
122 | yarn test # Run all tests, interactive and watch mode
123 | yarn test:once
124 | yarn test:coverage
125 | ```
126 |
127 | ### Versions
128 |
129 | #### SemVer
130 |
131 | We use Semantic Versioning for this project: https://semver.org/. (`vMAJOR.MINOR.PATCH`: `v1.0.1`)
132 |
133 | - Major version: Must be changed when Breaking Changes are made (public API isn't backward compatible).
134 | - A function has been renamed/removed from the public API
135 | - Something has changed that will cause the app to behave differently with the same configuration
136 | - Minor version: Must be changed when a new feature is added or updated (without breaking change nor behavioral change)
137 | - Patch version: Must be changed when any change is made that isn't either Major nor Minor. (Misc, doc, etc.)
138 |
139 | ### Releasing and publishing
140 |
141 | ```
142 | yarn releaseAndPublish # Shortcut - Will prompt for bump version, commit, create git tag, push commit/tag and publish to NPM
143 |
144 | yarn release # Will prompt for bump version, commit, create git tag, push commit/tag
145 | npm publish # Will publish to NPM
146 | ```
147 |
148 | > Don't forget we are using SemVer, please follow our SemVer rules.
149 |
150 | **Pro hint**: use `beta` tag if you're in a work-in-progress (or unsure) to avoid releasing WIP versions that looks legit
151 |
152 | ---
153 |
154 | ## Changelog
155 |
156 | > Our API change (including breaking changes and "how to migrate") are documented in the Changelog.
157 |
158 | See [changelog](./CHANGELOG.md)
159 |
160 | ---
161 |
162 | ## License
163 |
164 | MIT
165 |
166 | ---
167 |
168 | > This project was generated using https://github.com/UnlyEd/boilerplate-generator/tree/master/templates/typescript-OSS
169 |
170 | # Vulnerability disclosure
171 |
172 | [See our policy](https://github.com/UnlyEd/Unly).
173 |
174 | ---
175 |
176 | # Contributors and maintainers
177 |
178 | This project is being maintained by:
179 | - [Unly] Ambroise Dhenain ([Vadorequest](https://github.com/vadorequest)) **(active)**
180 |
181 | ---
182 |
183 | # **[ABOUT UNLY]**
184 |
185 | > [Unly](https://unly.org) is a socially responsible company, fighting inequality and facilitating access to higher education.
186 | > Unly is committed to making education more inclusive, through responsible funding for students.
187 |
188 | We provide technological solutions to help students find the necessary funding for their studies.
189 |
190 | We proudly participate in many TechForGood initiatives. To support and learn more about our actions to make education accessible, visit :
191 | - https://twitter.com/UnlyEd
192 | - https://www.facebook.com/UnlyEd/
193 | - https://www.linkedin.com/company/unly
194 | - [Interested to work with us?](https://jobs.zenploy.io/unly/about)
195 |
196 | Tech tips and tricks from our CTO on our [Medium page](https://medium.com/unly-org/tech/home)!
197 |
198 | #TECHFORGOOD #EDUCATIONFORALL
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | targets: {
7 | node: 'current',
8 | },
9 | },
10 | ],
11 | '@babel/preset-typescript',
12 | ],
13 | };
14 |
--------------------------------------------------------------------------------
/buildspec.yml:
--------------------------------------------------------------------------------
1 | version: 0.2
2 |
3 | env:
4 | # Please refer to https://github.com/UnlyEd/slack-codebuild
5 | variables:
6 | SLACK_WEBHOOK_URL: "https://hooks.slack.com/services/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"
7 | CODEBUILD_NOTIFY_ONLY_IF_FAIL: 1
8 | CC_TEST_REPORTER_ID: 119c96b7eb866b1e2a12e2bb86b96792a4b0a7353b7450c9b1cf4bc13286d4fd
9 |
10 | phases:
11 | install:
12 | runtime-versions:
13 | docker: 18
14 | nodejs: 10
15 | commands:
16 | - yarn --production=false # Install devDependencies (to run tests) - See https://yarnpkg.com/lang/en/docs/cli/install/#toc-yarn-install-production-true-false
17 | - yarn global add @unly/slack-codebuild
18 | - echo Installing codebuild-extras... # Install and execute aws-codebuild-extra, which adds env variables necessary on CodeBuild (including some for CodeClimate)
19 | - curl -fsSL https://raw.githubusercontent.com/UnlyEd/aws-codebuild-extras/master/install >> extras.sh
20 | - . ./extras.sh
21 |
22 | # See https://github.com/codeclimate/test-reporter/issues/379 for additional info regarding how to setup CodeBuild with CodeClimate
23 | pre_build:
24 | commands:
25 | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
26 | - chmod +x ./cc-test-reporter
27 | - ./cc-test-reporter before-build
28 |
29 | build:
30 | commands:
31 | - yarn test:coverage
32 |
33 | post_build:
34 | commands:
35 | - ./cc-test-reporter format-coverage -t lcov --prefix ${CODEBUILD_SRC_DIR} # Looks for ./coverage/lcov.info
36 | - ./cc-test-reporter after-build --debug -t lcov --exit-code $? # Uploads ./coverage/lcov.info and ./coverage/codeclimate.json
37 | finally:
38 | - slack-codebuild
39 |
--------------------------------------------------------------------------------
/examples/with-next/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | .env*
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
--------------------------------------------------------------------------------
/examples/with-next/README.md:
--------------------------------------------------------------------------------
1 | # Universal Language Detector - With Next.js example
2 |
3 | See the [_app.js](./pages/_app.js) file, that's where the magic happens.
4 |
5 | In this demo, we automatically resolve the language for all pages through the _app file, which makes the `lang` variable available in all pages.
6 |
7 | It works from the server side (SSR), and upon client side navigation too
8 |
9 | ---
10 |
11 | ## Demo
12 |
13 | [https://universal-language-detector.now.sh/](https://universal-language-detector.now.sh/)
14 |
15 | ---
16 |
17 | ## Contributing
18 |
19 | ### Development
20 |
21 | `yarn start`
22 |
23 | ### Deploying
24 |
25 | `yarn deploy`
26 |
27 | ### Deploying to production
28 |
29 | `yarn deploy:production`
30 |
--------------------------------------------------------------------------------
/examples/with-next/components/footer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import packageJson from '../package'
3 |
4 | const footer = (props) => {
5 | const uldVersion = packageJson.dependencies['@unly/universal-language-detector'];
6 |
7 | return (
8 | <>
9 |