What is the process of creating locale aliases in typesafe-i18n?

Motivation

Throughout history, the Chinese language has been associated with multiple language codes (RFC 5646 with ISO-639 zh). The most commonly used ones include zh-CN (Simplified Hanzi Script of Chinese Mandarin primarily used in PRC, etc.), zh-TW (Traditional Hanzi Script of Chinese Mandarin mainly used in Taiwan, etc.), and zh (often synonymous with zh-CN). There are also less utilized codes like zh-HanS and zh-HanT, which have similar effects to zh-CN and zh-TW respectively, but without specified regions.

The upcoming ECMAScript Intl API will assign distinct display names to all these codes, carrying with them regional and political connotations. To maintain neutrality in my application, I prefer using zh-HanS and zh-HanT instead of zh-CN and zh-TW.

Problem

Most modern browsers always send Accept-Language: zh-CN; zh; for zh-CN/zh-HanS, and Accept-Language: zh-TW; zh; for zh-TW/zh-HanT in HTTP headers. As a result, if I use src/i18n/zh-HanS/ src/i18n/zh-HanT in my application, the

detectLocale(initAcceptLanguageHeaderDetector({headers})
function of typesafe-i18n will fail to identify the correct locale, attempt to fallback to zh, and ultimately end up at the baseLocale (en).

Question

How can I create aliases for these codes and ensure the detector correctly falls back to the intended language?

Answer №1

The detectLocale function is generated and defined in the following way in the file src/i18n/i18n-util.ts, utilizing the variable locales which represents a list of locale files.

// src/i18n/i18n-util.ts
import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors'

// [...]

export const locales: Locales[] = [
    'en',
    'ja',
    'zh-HanS',
    'zh-HanT'
]

// [...]

export const detectLocale = (...detectors: LocaleDetector[]) => detectLocaleFn<Locales>(baseLocale, locales, ...detectors)

In this scenario, it is necessary to utilize the detectLocaleFn mentioned above instead of

detectLocale from 'typesafe-i18n/detectors'
.

Within your detection code:

import detectLocale from 'typesafe-i18n/detectors'

// [...]

// Alias table
const LOCALE_ALIAS = new Map<string, Locales>([
  ['zh-CN', 'zh-HanS'],
  ['zh-TW', 'zh-HanT'],
  ['zh-HK', 'zh-HanT'],
  ['zh', 'zh-HanS'],
])
// for initAcceptLanguageHeaderDetector
const headers = getHeaders(request)
const acceptLanguageDetector = initAcceptLanguageHeaderDetector({ headers })

// detection
const locale = detectLocale<Locales>(baseLocale, [...locales, ...LOCALE_ALIAS.keys()] as Locales[], acceptLanguageDetector)

const aliasedLocale = LOCALE_ALIAS.get(locale) ?? locale
console.log(`Detected locale: ${locale}, aliased to: ${aliasedLocale}`)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can jq handle synchronous functions?

The usage of jq.run('.', '/path/to/file.json').then(console.log) appears to be causing asynchronous behavior, leading to the output being displayed as Promise { <pending> }. This delay in obtaining the result is problematic, promp ...

What could be causing the jQuery effect to not function properly?

After completing a course on Codecademy, I successfully ran the code. However, I prefer to copy and paste the code into my own jquery folder for future reference and practice. The objective of this project was to make the element 'krypton' bounc ...

Is there a way to retrieve the filename from a callback in gulp-contains?

Currently, I am utilizing gulp-contains to scan for a specific string. If the target string is found, I intend to trigger an error message stating "String found in file abc." The 'file' parameter holds the entire object comprising filename + Buff ...

How do I implement an array of objects using an interface in React and Typescript?

I'm working with an array of objects where the data is stored in a JSON file. Here's a glimpse of the JSON file: [ { "_id": "62bd5fba34a8f1c90303055c", "index": 0, "email": "<a href="/cdn-cgi/l/emai ...

The flow of events is not hindered by an if statement, even when the code within it is executed

I'm facing an issue where the console.log statement keeps executing even after calling the search function within the "if statements" in my code. Is there a way to prevent this from happening? function search() { /** * The Tweet checking algori ...

ESLint and Prettier are butting heads when trying to run their commands consecutively

My package.json file includes two commands: "format": "prettier --write \"{src,{tests,mocks}}/**/*.{js,ts,vue}\"", "lint": "eslint . -c .eslintrc.js --rulesdir eslint-internal-rules/ --ext .ts,.js,.vue ...

Generate a fresh row in a table with user inputs and save the input values when the "save" button is

HTML: <tbody> <tr id="hiddenRow"> <td> <button id="saveBtn" class="btn btn-success btn-xs">save</button> </td> <td id="firstName"> <input id="first" type="tex ...

AngularJS enables you to easily manipulate image width and height using the ng-file-upload feature

Seeking assistance with validating image width and height based on a 1:3 ratio prior to uploading using ng-file-upload. The validation should occur before sending the image to the server. Unsure how to retrieve the dimensions of the selected image for val ...

Ways to address the issue of duplicated names in input fields

Currently, I am utilizing a React Hook Form hook known as useFieldsArray. This hook is responsible for rendering an array of fields, each containing an object with the data that will be transmitted via the input. One interesting feature is the ability to ...

Typescript: defining an interface that inherits properties from a JSON type

When working with TypeScript, I've utilized a generic JSON type as suggested in this source: type JSONValue = | string | number | boolean | null | JSONValue[] | {[key: string]: JSONValue} My goal is to cast interface types matching JSON to and ...

Tips for looping through an array of objects and summing their attributes

Here we have an array of objects as an example: [{Name: Deji, Age: 12}, {Name: Sonia, Age: 13}, {Name: Fabio, Age: 21}] I am curious about how to loop through this array in order to calculate the total age of all the people included. Is there a specific ...

Customizing the appearance of table column labels in BootstrapVue

Seeking help with formatting my table labels to display as defined in the code. Currently, the labels only capitalize the first character of the word and ignore the rest. Any suggestions on how to achieve the desired value for label display? Currently, IP ...

What is the best method to assign a property to a model within AngularJS by utilizing an attribute parameter?

I am in the process of creating a custom directive in AngularJS for a UI slider that can be used multiple times. Each slider should be able to bind to a specific property. My idea was to use an attribute called "property" which would automatically update w ...

What is the process of calculating the average of JSON data and looping through it multiple times using Javascript?

I've encountered a JSON data set that has the following structure: { name: "Evelyn", assignment: "SCRUM", difficulty: 3, fun: 4 } And so on. My goal is to calculate the average value of both difficulty and fun for e ...

Does anyone have insight on which JavaScript library is being utilized in this context?

While perusing an interesting article, I came across an image that caught my attention. Clicking on it revealed a unique way to view the full size. I am curious if anyone knows which JavaScript library was used for this effect. You can find the article her ...

JavaScript validation for basic "select" isn't functioning as expected

I need assistance with my simple "select" validation using JavaScript. The issue I am facing is that when validating the "select" element, it does not display the select options to users after a validation error occurs. "The select option is not re-enabl ...

Unable to make custom font work in TailwindCSS and ReactJS project

I have incorporated a custom font into my projects using React, TypeScript, TailWind, and NextJS. The font file is stored in the /fonts directory with the name Glimer-Regular.ttf. To implement the font, I added the following code snippet to my global.css ...

Sending a request from JavaScript to C# methods using AJAX, with no expected response, within an ASP.NET MVC framework

Setting up the Environment: <package id="jQuery" version="3.2.1" targetFramework="net45" /> <package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" /> Recently, I encountered an issue while trying to send a request from one ...

Failure to send Websocket connection

Currently working on PHP, here's a snippet: $room_array = array(); $room_array[0] = 'room-list'; $room_array['info'] = array('room_name' => $room['room_name'], 'owner' => $username['usernam ...

Obtain a particular column from a JSON document using Angular 2

Currently, I am working on a project in Angular2 that requires the use of an online JSON file. I have utilized http.get to retrieve the file, but I only need the data from the second and third columns which contain the first name and last name. If you wan ...