Skip to content

Commit c9b62ff

Browse files
committed
write middleware for lingui
1 parent f818b4e commit c9b62ff

10 files changed

+7980
-5
lines changed

.babelrc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"presets": ["next/babel"],
3+
"plugins": [
4+
"macros"
5+
]
6+
}

.editorconfig

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
root = true
2+
[*]
3+
end_of_line = lf
4+
insert_final_newline = true
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
max_line_length = 100

.eslintrc

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"extends": ["standard", "standard-react"],
3+
"plugins": ["react-hooks"],
4+
"parser": "babel-eslint",
5+
"env": {
6+
"browser": true,
7+
"node": true
8+
},
9+
"parserOptions": {
10+
"ecmaFeatures": {
11+
"jsx": true
12+
},
13+
"sourceType": "module"
14+
},
15+
"rules": {
16+
"comma-dangle": ["error", "always-multiline"],
17+
"react-hooks/rules-of-hooks": "error"
18+
}
19+
}

.gitignore

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
# Created by https://www.gitignore.io/api/node
3+
# Edit at https://www.gitignore.io/?templates=node
4+
5+
### Node ###
6+
# Logs
7+
logs
8+
*.log
9+
npm-debug.log*
10+
yarn-debug.log*
11+
yarn-error.log*
12+
13+
# Runtime data
14+
pids
15+
*.pid
16+
*.seed
17+
*.pid.lock
18+
19+
# Directory for instrumented libs generated by jscoverage/JSCover
20+
lib-cov
21+
22+
# Coverage directory used by tools like istanbul
23+
coverage
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+
# Optional npm cache directory
48+
.npm
49+
50+
# Optional eslint cache
51+
.eslintcache
52+
53+
# Optional REPL history
54+
.node_repl_history
55+
56+
# Output of 'npm pack'
57+
*.tgz
58+
59+
# Yarn Integrity file
60+
.yarn-integrity
61+
62+
# dotenv environment variables file
63+
.env
64+
.env.test
65+
66+
# parcel-bundler cache (https://parceljs.org/)
67+
.cache
68+
69+
# next.js build output
70+
.next
71+
72+
# nuxt.js build output
73+
.nuxt
74+
75+
# vuepress build output
76+
.vuepress/dist
77+
78+
# Serverless directories
79+
.serverless/
80+
81+
# FuseBox cache
82+
.fusebox/
83+
84+
# DynamoDB Local files
85+
.dynamodb/
86+
87+
# End of https://www.gitignore.io/api/node

.linguirc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"localeDir": "src/locales/",
3+
"srcPathDirs": ["src/", "pages/"],
4+
"srcPathIgnorePatterns": [
5+
"/node_modules/",
6+
"/.next/",
7+
],
8+
"format": "minimal",
9+
"sourceLocale": "ru",
10+
"compileNamespace": "window.LINGUI_CATALOG"
11+
}

lib/middleware.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
const pathMatch = require('path-match')()
2+
3+
/**
4+
*
5+
* @param {object} options
6+
* @param {import('next').Server} nextApp
7+
* @returns {import('express').Handler[]}
8+
*/
9+
function createMiddleware ({ locales, defaultLocale, subPaths, ignoreRoutes }, nextApp) {
10+
const localesWithoutDefault = () => locales.filter(lang => lang !== defaultLocale)
11+
const forseTrallingSlash = (path) => localesWithoutDefault().some(lng => path === `/${lng}`) ? `${path}/` : path
12+
const ignoreRegex = new RegExp(`^/(?!${ignoreRoutes.map(x => x.replace('/', '')).join('|')}).*$`)
13+
const ignoreRoute = pathMatch(ignoreRegex)
14+
const isI18nRoute = req => ignoreRoute(req.url) && req.method === 'GET'
15+
console.log(`/:lang(${localesWithoutDefault()
16+
.join('|')})?/*`)
17+
const routeWithLang = pathMatch(`/:lang(${localesWithoutDefault()
18+
.join('|')})?/*`)
19+
const parseRoute = pathname => routeWithLang(pathname)
20+
/**
21+
* @type {import('express').Handler[]}
22+
*/
23+
const middlewares = []
24+
25+
middlewares.push((req, res, next) => {
26+
if (isI18nRoute(req)) {
27+
req.lingui = {
28+
locale: req.cookies.locale || req.acceptsLanguages(locales) || defaultLocale,
29+
locales,
30+
defaultLocale,
31+
}
32+
}
33+
next()
34+
})
35+
36+
if (subPaths) {
37+
middlewares.push((req, res, next) => {
38+
if (!isI18nRoute(req)) return next()
39+
const pathname = forseTrallingSlash(req.path)
40+
const { lang, 0: otherPath } = parseRoute(pathname)
41+
const { lingui: { locale: userLocale } } = req
42+
req.url = otherPath ? `/${otherPath}` : '/'
43+
44+
if (userLocale === defaultLocale && lang == null) {
45+
return next()
46+
}
47+
48+
if (userLocale === lang) {
49+
return next()
50+
}
51+
52+
if (userLocale === defaultLocale && lang != null) {
53+
return res.redirect(`/${otherPath}`)
54+
}
55+
56+
return res.redirect(`/${userLocale}${otherPath ? `/${otherPath}` : ''}`)
57+
})
58+
}
59+
60+
return middlewares
61+
}
62+
63+
module.exports = createMiddleware

next.config.js

Whitespace-only changes.

0 commit comments

Comments
 (0)