diff --git a/app/templates/completed.js b/app/templates/completed.js
index 3ebc5020..18d0ce13 100644
--- a/app/templates/completed.js
+++ b/app/templates/completed.js
@@ -15,9 +15,9 @@ module.exports = function(state, emit) {
-
+
diff --git a/package-lock.json b/package-lock.json
index 7151feab..cb834b57 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -42,15 +42,6 @@
"through": "2.3.8"
}
},
- "accept-language": {
- "version": "3.0.18",
- "resolved": "https://registry.npmjs.org/accept-language/-/accept-language-3.0.18.tgz",
- "integrity": "sha1-9QJfF79lpGaoRYOMz5jNuHfYM4Q=",
- "requires": {
- "bcp47": "1.1.2",
- "stable": "0.1.6"
- }
- },
"accepts": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
@@ -1236,11 +1227,6 @@
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
"dev": true
},
- "bcp47": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz",
- "integrity": "sha1-NUvjMH/9CEM6ePXh4glYRfifx/4="
- },
"bel": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/bel/-/bel-5.1.5.tgz",
@@ -1736,6 +1722,11 @@
"chalk": "1.1.3"
}
},
+ "cldr-core": {
+ "version": "32.0.0",
+ "resolved": "https://registry.npmjs.org/cldr-core/-/cldr-core-32.0.0.tgz",
+ "integrity": "sha1-M7OO+WyaGD9SilZGBJRaqqTs6nE="
+ },
"clean-css": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz",
@@ -3481,15 +3472,6 @@
}
}
},
- "express-request-language": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/express-request-language/-/express-request-language-1.1.15.tgz",
- "integrity": "sha512-KiLUdEZCcgwh8qfIvkCrhz1MMAFx/Xj4UcspN4zUxVdp+bp+yFvqUMmlyMHK2nC5JlQV7VK5uFOoS5LrArTL1A==",
- "requires": {
- "accept-language": "3.0.18",
- "bcp47": "1.1.2"
- }
- },
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
@@ -10864,11 +10846,6 @@
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
- "stable": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz",
- "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA="
- },
"stack-trace": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
diff --git a/package.json b/package.json
index dde799d4..ea7a9776 100644
--- a/package.json
+++ b/package.json
@@ -96,10 +96,10 @@
"aws-sdk": "^2.149.0",
"body-parser": "^1.18.2",
"choo": "^6.5.1",
+ "cldr-core": "^32.0.0",
"connect-busboy": "0.0.2",
"convict": "^4.0.1",
"express": "^4.16.2",
- "express-request-language": "^1.1.15",
"fluent": "^0.4.1",
"fluent-langneg": "^0.1.0",
"helmet": "^3.9.0",
diff --git a/server/languages.js b/server/languages.js
index e6d1f551..d9121eef 100644
--- a/server/languages.js
+++ b/server/languages.js
@@ -4,11 +4,9 @@ const fs = require('fs');
const path = require('path');
function allLangs() {
- const langs = fs.readdirSync(
+ return fs.readdirSync(
path.join(__dirname, '..', 'dist', 'public', 'locales')
);
- langs.unshift('en-US'); // default first, TODO change for fluent-langneg
- return langs;
}
if (config.l10n_dev) {
diff --git a/server/routes/index.js b/server/routes/index.js
index 4493c7d5..97ab2ca7 100644
--- a/server/routes/index.js
+++ b/server/routes/index.js
@@ -1,20 +1,40 @@
const busboy = require('connect-busboy');
const helmet = require('helmet');
const bodyParser = require('body-parser');
-const requestLanguage = require('express-request-language');
const languages = require('../languages');
const storage = require('../storage');
const config = require('../config');
const pages = require('./pages');
-// const lang = require('fluent-langneg')
+const { negotiateLanguages } = require('fluent-langneg');
const IS_DEV = config.env === 'development';
+const acceptLanguages = /(([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\*)(;q=[0-1](\.[0-9]+)?)?/g;
+const langData = require('cldr-core/supplemental/likelySubtags.json');
module.exports = function(app) {
- app.use(
- requestLanguage({
- languages
- })
- );
+ app.use(function(req, res, next) {
+ const header = req.headers['accept-language'] || 'en-US';
+ if (header.length > 255) {
+ req.language = 'en-US';
+ return next();
+ }
+ const langs = header.replace(/\s/g, '').match(acceptLanguages);
+ const preferred = langs
+ .map(l => {
+ const parts = l.split(';');
+ return {
+ locale: parts[0],
+ q: parts[1] ? parseFloat(parts[1].split('=')[1]) : 1
+ };
+ })
+ .sort((a, b) => b.q - a.q)
+ .map(x => x.locale);
+ req.language = negotiateLanguages(preferred, languages, {
+ strategy: 'lookup',
+ likelySubtags: langData.supplemental.likelySubtags,
+ defaultLocale: 'en-US'
+ })[0];
+ next();
+ });
app.use(helmet());
app.use(
helmet.hsts({