From 9b53ccc9ded393dbdb4c8c83902ddc66fc1d2ced Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Thu, 12 Mar 2026 23:36:48 +0800 Subject: [PATCH] fix(i18n): handle POSIX locale values in getLocale(), closes #3518 (#3522) When LANG=C.UTF-8, navigator.language can return 'C' which is not a valid BCP 47 tag, causing Intl.NumberFormat and toLocaleString to throw. Normalize POSIX values (C, C.UTF-8, POSIX) to 'en-US' at the source. Co-authored-by: Claude Opus 4.6 --- apps/readest-app/src/app/user/components/PlanCard.tsx | 7 ++++--- apps/readest-app/src/utils/misc.ts | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/readest-app/src/app/user/components/PlanCard.tsx b/apps/readest-app/src/app/user/components/PlanCard.tsx index 13a3d834..2c8ed916 100644 --- a/apps/readest-app/src/app/user/components/PlanCard.tsx +++ b/apps/readest-app/src/app/user/components/PlanCard.tsx @@ -29,9 +29,10 @@ const PlanCard: React.FC = ({ }) => { const _ = useTranslation(); const { price, currency } = plan; - const formattedPrice = new Intl.NumberFormat(getLocale(), { style: 'currency', currency }).format( - price / 100, - ); + const formattedPrice = new Intl.NumberFormat(getLocale(), { + style: 'currency', + currency, + }).format(price / 100); return (
{ }; export const getLocale = () => { - return localStorage?.getItem('i18nextLng') || navigator?.language || ''; + const locale = localStorage?.getItem('i18nextLng') || navigator?.language || ''; + // POSIX locale values (e.g. 'C', 'C.UTF-8', 'POSIX') are not valid BCP 47 + // tags and would cause Intl/toLocaleString to throw — fall back to en-US + if (!locale || /^(C|POSIX)(\..*)?$/i.test(locale)) return 'en-US'; + return locale; }; export const getUserLang = () => {