1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
import { en, type MessageKey } from './en';
import { da } from './da';
// Add a catalog and register its BCP 47 locale here to support another language.
// Missing messages always fall back to English. Locale selection belongs to the shell.
const catalogs: Record<string, Partial<Record<MessageKey, string>>> = { en, da };
export const defaultLocale = 'en';
export type Parameters = Record<string, string | number>;
export function createI18n(requestedLocale = defaultLocale) {
const locale = Object.hasOwn(catalogs, requestedLocale) ? requestedLocale : defaultLocale;
const catalog = catalogs[locale];
return {
locale,
t(key: MessageKey, parameters: Parameters = {}): string {
const message = catalog[key] ?? en[key];
return message.replace(/\{(\w+)\}/g, (_, name: string) => String(parameters[name] ?? `{${name}}`));
},
number(value: number, options: Intl.NumberFormatOptions = {}): string {
return new Intl.NumberFormat(locale, { maximumFractionDigits: 2, ...options }).format(
Object.is(value, -0) ? 0 : value,
);
},
};
}
export type I18n = ReturnType<typeof createI18n>;
export type { MessageKey };
|