
Better Auth i18n 插件完全指南基于語言檢測的認證錯誤消息國際化方案【免費下載鏈接】better-authThe most comprehensive authentication framework項目地址: https://gitcode.com/GitHub_Trending/be/better-auth導讀better-auth/i18n是 Better Auth 官方提供的國際化i18n插件用于根據檢測到的用戶語言區域locale自動翻譯認證接口返回的錯誤消息例如把INVALID_EMAIL_OR_PASSWORD從英文 Invalid email or password 翻譯為法文、德文或中文。本文以 packages/i18n/README.md 為骨架結合 插件核心實現、類型定義 與 完整測試用例完整講解插件的安裝、四種語言檢測策略、全部配置項以及源碼級工作原理幫助你在一鍵啟用 22 種內置語言的同時掌握自定義翻譯與兜底機制的實戰技巧。一、安裝better-auth/i18n是一個獨立的 npm 包與better-auth主框架配合使用可通過 pnpm / npm / yarn 安裝npm install better-auth/i18n從 packages/i18n/package.json 可以看到該包聲明better-auth與better-auth/core為 peerDependenciesworkspace:^即它必須與 Better Auth 核心框架在同一項目中共同使用包本身以 ESM 形式發布main/module均指向./dist/index.mjs并提供了三個導出入口.主入口導出i18n插件工廠與locales內置語言集合./client客戶端入口導出i18nClient用于在createAuthClient中獲得服務端插件的類型推斷./locales單獨導出全部內置翻譯字典。當前倉庫中該包的版本為1.7.3見 CHANGELOG.md22 種內置語言在 1.7.0 版本引入。二、內置翻譯開箱即用的 22 種語言插件隨包攜帶 22 種語言的完整翻譯字典覆蓋了全球主要語種。全部語言文件位于 packages/i18n/src/locales/并通過 locales/index.ts 統一導出| 代碼 | 語言 | | 代碼 | 語言 | |------|------|-|------|------| |ar| 阿拉伯語 | |nl| 荷蘭語 | |bn| 孟加拉語 | |pl| 波蘭語 | |de| 德語 | |pt| 葡萄牙語 | |en| 英語 | |ru| 俄語 | |es| 西班牙語 | |sv| 瑞典語 | |fa| 波斯語法爾西語 | |th| 泰語 | |fr| 法語 | |tr| 土耳其語 | |hi| 印地語 | |uk| 烏克蘭語 | |id| 印度尼西亞語 | |vi| 越南語 | |it| 意大利語 | |zh| 簡體中文 | |ja| 日語 | |ko| 韓語 |每種語言都是一個TranslationDictionary對象。以 英文默認字典 為例它覆蓋了 34 個核心錯誤碼包括USER_NOT_FOUND、INVALID_EMAIL_OR_PASSWORD、PASSWORD_TOO_SHORT、TOKEN_EXPIRED、EMAIL_NOT_VERIFIED、SESSION_EXPIRED、ACCOUNT_NOT_FOUND等認證場景中的高頻錯誤。簡體中文翻譯見 zh.ts例如INVALID_EMAIL_OR_PASSWORD對應郵箱或密碼無效SESSION_EXPIRED對應會話已過期請重新驗證身份以執行此操作。從測試用例 i18n.test.ts 可以確認項目對每種內置語言都做了完整性校驗USER_NOT_FOUND、INVALID_PASSWORD、INVALID_EMAIL、INVALID_EMAIL_OR_PASSWORD、EMAIL_NOT_VERIFIED、PASSWORD_TOO_SHORT、PASSWORD_TOO_LONG、USER_ALREADY_EXISTS、SESSION_EXPIRED、ACCOUNT_NOT_FOUND這 10 個關鍵錯誤碼必須存在于所有語言字典中且值必須是非空字符串。使用全部內置語言在betterAuth配置中掛載插件translations直接傳入locales即可啟用全部 22 種語言import { betterAuth } from better-auth; import { i18n, locales } from better-auth/i18n; export const auth betterAuth({ plugins: [ i18n({ translations: locales }), ], });使用語言子集如果只需要服務特定市場可以只挑選部分語言減小打包體積import { i18n, locales } from better-auth/i18n; export const auth betterAuth({ plugins: [ i18n({ translations: { en: locales.en, fr: locales.fr, }, }), ], });注意translations中實際提供的語言代碼就是插件可識別的全部語言集合——檢測到不在集合中的語言時會回退到默認語言詳見下文語言檢測與兜底。三、覆蓋與擴展翻譯覆蓋特定錯誤消息當某個內置翻譯不符合你的產品文案風格時可以基于內置字典做淺合并覆蓋無需重建整個字典import { i18n, locales } from better-auth/i18n; export const auth betterAuth({ plugins: [ i18n({ translations: { ...locales, fr: { ...locales.fr, USER_NOT_FOUND: Membre introuvable, }, }, }), ], });添加自定義語言TranslationDictionary的類型是Partial錯誤碼集合 Recordstring, string見 types.ts即除了內置錯誤碼你還可以為插件擴展的其他錯誤碼提供翻譯甚至加入自己的自定義鍵import { i18n, locales } from better-auth/i18n; import type { TranslationDictionary } from better-auth/i18n; const myLocale: TranslationDictionary { USER_NOT_FOUND: ..., INVALID_EMAIL_OR_PASSWORD: ..., // ... 其他錯誤碼 }; export const auth betterAuth({ plugins: [ i18n({ translations: { ...locales, xx: myLocale, }, }), ], });值得說明的是TranslationDictionary通過UnionToIntersection類型體操自動聚合了 Better Auth 插件注冊表中所有插件聲明的錯誤碼見 types.ts因此當你同時使用其他插件如組織、API Key 等并為其聲明了$ERROR_CODES時自定義字典會獲得這些錯誤碼的完整類型提示在編譯期就能發現遺漏。四、語言檢測策略header / cookie / session / callback插件根據detection數組中的策略按優先級順序逐一嘗試檢測用戶語言命中即返回。支持四種策略見 types.ts其實現全部位于 src/index.ts策略說明檢測來源header解析請求的Accept-Language頭ctx.headerscookie讀取指定名稱的 Cookie 值Cookie頭session讀取當前會話用戶記錄中的語言字段ctx.context.session.usercallback調用自定義的getLocale函數用戶自定義邏輯1. header默認策略默認配置下插件只啟用header策略。它會先調用內部的parseAcceptLanguage函數src/index.ts解析Accept-Language頭按;拆分出每個語言及其q質量值按質量值降序排序并把形如fr-CA的區域碼裁剪為基礎語言碼fr然后返回第一個存在于translations中的語言。例如請求頭Accept-Language: es;q0.9, fr;q0.8, en;q0.7而你的translations只有 en/fr/de 時檢測結果會是fr因為es不在支持集合內測試見 i18n.test.ts請求頭fr-CA也會正確落到fr測試見 i18n.test.ts。2. cookie當用戶在應用內手動切換語言時通常希望把選擇持久化到 Cookie。啟用cookie策略后插件會解析Cookie頭并讀取localeCookie指定的 Cookie默認名為locale若其值在支持的語言集合中則采用i18n({ translations: { en: locales.en, fr: locales.fr }, detection: [cookie, header], // cookie 優先header 兜底 localeCookie: lang, // 自定義 Cookie 名稱 })測試用例驗證了優先級行為當Cookie: langfr且Accept-Language: de同時存在、detection順序為[cookie, header]時最終使用 Cookie 中的法語見 i18n.test.ts。3. session對于登錄用戶可以直接讀取用戶資料中保存的語言偏好。插件從ctx.context.session.user中讀取userLocaleField指定的字段默認字段名也是locale。這意味著你可以在用戶表上擴展一個locale字段讓用戶的語言選擇跟隨賬號跨設備同步。4. callbackcallback策略提供最大靈活性它調用getLocale(ctx)函數你可以從任意來源決定語言例如自定義請求頭、子域名或數據庫查詢i18n({ translations: { en: locales.en, fr: locales.fr }, detection: [callback], getLocale: (ctx) { return ctx.headers?.get(X-Custom-Locale) ?? null; }, })從測試可見getLocale既支持同步返回值也支持Promise見 types.ts并且即使請求對象未定義如直接調用auth.api的場景回調仍會被正常調用見 i18n.test.ts。五、完整配置項一覽所有配置項匯總如下均來自 types.ts 與 src/index.ts 的默認值合并邏輯配置項類型默認值說明translations{ [locale]: TranslationDictionary }必填語言代碼到翻譯字典的映射為空時插件直接拋出i18n plugin: translations object is empty錯誤測試見 i18n.test.tsdefaultLocalestringen所有檢測策略都失敗時使用的兜底語言。規則顯式指定且存在于translations時優先使用否則若集合中有en則用enen也不存在時使用集合中第一個語言detectionLocaleDetectionStrategy[][header]語言檢測策略數組按數組順序依次嘗試第一個命中即生效localeCookiestringlocalecookie策略讀取的 Cookie 名稱userLocaleFieldstringlocalesession策略讀取的用戶字段名getLocale(ctx) string \| null \| Promise...無callback策略使用的自定義檢測函數defaultLocale的解析邏輯見 src/index.ts它優先采納顯式傳入且存在于翻譯集合中的值否則當集合包含en時回退為enen缺失時采用集合中第一個語言。測試用例覆蓋了這三種情況以及未提供defaultLocale且無en時保持原始英文消息的行為見 i18n.test.ts。六、工作原理after 鉤子 APIError 重拋了解插件如何翻譯錯誤有助于你排查自定義場景。插件實現位于 src/index.ts它注冊了一個匹配所有請求的after鉤子攔截錯誤響應從ctx.context.returned取出請求返回結果僅當它是APIErrorisAPIError判斷時才繼續處理——正常響應、非錯誤響應直接跳過測試驗證了成功響應不會被改動見 i18n.test.ts提取錯誤碼從錯誤體returned.body中取出code字符串這是后續查字典的鍵檢測語言調用detectLocale(ctx)按detection順序解析當前請求的語言查字典并重拋在opts.translations[locale]?.[errorCode]中查找翻譯。若找到則用原 HTTP 狀態碼和錯誤碼重新拋出一個APIError新錯誤體包含三個字段code原始錯誤碼保持不變message翻譯后的本地化消息originalMessage翻譯前的原始英文消息便于調試與日志記錄。若找不到對應翻譯例如該錯誤碼未收錄則保持原樣返回不進行任何修改見 i18n.test.ts 的兜底行為驗證。由于翻譯發生在服務端統一的after鉤子中所有認證端點登錄、注冊、找回密碼、會話校驗等的錯誤消息都會自動本地化客戶端無需改動任何請求邏輯。七、客戶端類型推斷i18nClient雖然翻譯完全在服務端完成官方仍建議在客戶端同步掛載i18nClient以獲得服務端插件配置的類型推斷例如$InferServerPlugin帶來的端到端類型安全import { createAuthClient } from better-auth/client; import { i18nClient } from better-auth/i18n/client; export const client createAuthClient({ plugins: [i18nClient()], });客戶端實現見 src/client.ts它聲明了與服務端相同的插件id: i18n并通過$InferServerPlugin完成類型關聯。注意客戶端不承擔翻譯邏輯——錯誤消息已經由服務端按檢測到的語言翻譯完畢客戶端插件只負責類型層面的銜接。八、驗證與測試倉庫為插件提供了覆蓋全面的單元測試 i18n.test.ts共覆蓋八個維度基于Accept-Language頭的檢測法語、德語、質量值排序、fr-CA基礎碼裁剪、不可用語言回退基于 Cookie 的檢測及其與 header 的優先級翻譯缺失時的兜底行為getLocale回調檢測及無請求場景非錯誤響應不被改動defaultLocale的三種解析分支與空翻譯集合報錯內置語言的完整性22 個語言全部導出、10 個關鍵錯誤碼非空。你可以在倉庫根目錄運行對應包測試來驗證當前行為pnpm --filter better-auth/i18n test總結better-auth/i18n用極低的接入成本一個插件、一個translations配置為 Better Auth 的認證錯誤消息提供了完整的國際化能力22 種內置語言開箱即用header/cookie/session/callback四種檢測策略覆蓋從瀏覽器自動匹配到用戶手動選擇、跨設備同步的全部場景defaultLocale與翻譯缺失保持原文的雙重兜底機制保證了任何情況下接口都不會出現空消息。若需深度定制TranslationDictionary類型會隨插件注冊表自動聚合錯誤碼配合getLocale回調你可以將任何自定義語言檢測邏輯無縫接入認證流程。【免費下載鏈接】better-authThe most comprehensive authentication framework項目地址: https://gitcode.com/GitHub_Trending/be/better-auth創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考