aboutsummaryrefslogtreecommitdiff
path: root/src/i18n/index.ts
blob: 2f46dd0a2d1311b316a5ea46734ec001042202d3 (plain) (blame)
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 };