Skip to content

Commit 9cca1fb

Browse files
author
Simon Planinschek
committed
Add ServerInternationalization class for handling languages on the server side
1 parent d23de20 commit 9cca1fb

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

src/ServerInternationalization.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { IncomingMessage } from 'http'
2+
import { getCookieFromRequest } from './utilities'
3+
import ClientInternationalization from './ClientInternationalization'
4+
5+
class ServerInternationalization<
6+
T extends string
7+
> extends ClientInternationalization<T> {
8+
/**
9+
* ServerInternationalization utility package for working with languages
10+
*
11+
*
12+
* @param supportedLanguages { Array<string> } - List of all supported languages
13+
* @param fallbackLanguage { string } - Fallback language if no language matches
14+
* @param cookieName { string } - Optional: Set a preferred cookie name
15+
*/
16+
constructor(
17+
supportedLanguages: Array<T>,
18+
fallbackLanguage: T,
19+
cookieName: string
20+
) {
21+
super(supportedLanguages, fallbackLanguage, cookieName)
22+
}
23+
24+
/**
25+
* Get the current language
26+
* This method will first check if a language cookie is present.
27+
* If no cookie was found the method will get the language form the browser
28+
*
29+
* @return { string } - Found language or fallback language
30+
*/
31+
detectLanguage(request?: IncomingMessage): T {
32+
// Check if request is not undefined
33+
if (request) {
34+
// Try to get language form cookie
35+
const cookieFromRequest = getCookieFromRequest(this.cookieName, request)
36+
37+
if (cookieFromRequest) {
38+
return cookieFromRequest as T
39+
}
40+
41+
// Get accept language from request header
42+
const acceptLanguage = request.headers['accept-language']
43+
44+
if (acceptLanguage) {
45+
// Extract the locale string and the priority from header string
46+
const requestedLocales = acceptLanguage.split(',').map((part) => {
47+
const [locale, priority] = part.trim().split(';q=')
48+
49+
return { locale, priority: parseInt(priority) }
50+
})
51+
52+
// Get the potential locale from requested locales array
53+
const potentialLocale = requestedLocales
54+
.sort((a, b) => b.priority - a.priority)
55+
.find(
56+
({ locale }) =>
57+
locale !== '*' &&
58+
this.supportedLanguages.some((lang) => locale === lang)
59+
)
60+
61+
// Check if the potential locale is not undefined else return the fallback language
62+
return (potentialLocale
63+
? potentialLocale.locale
64+
: this.fallbackLanguage) as T
65+
}
66+
}
67+
68+
return this.detectBrowserLanguage()
69+
}
70+
}
71+
72+
export default ServerInternationalization

0 commit comments

Comments
 (0)