A custom plugin for better-auth that allows you to localize your error messages.
npm install better-auth-localizationA localization plugin for Better Auth that automatically translates error messages from the core library and official plugins.
!ezgif-6723e2cdfd4aa9
- ๐ Multi-language support - Built-in translations with easy custom locale addition
- ๐ Automatic translation - Seamlessly translates error messages without changing your application logic
- ๐ฏ Type-safe - Full TypeScript support with autocomplete for custom translations
- ๐ก๏ธ Fallback system - Fallback to default messages when translations are missing
- ๐ง Flexible locale detection - Support for custom locale resolution from headers, cookies, or databases
- โก Zero runtime overhead - Translations are bundled at build time
``bash`
npm install better-auth-localizationor
yarn add better-auth-localizationor
pnpm add better-auth-localization
`typescript
import { betterAuth } from "better-auth";
import { localization } from "better-auth-localization";
export const auth = betterAuth({
// ... your config
plugins: [
localization({
defaultLocale: "pt-BR", // Use built-in Portuguese translations
fallbackLocale: "default" // Fallback to English
})
]
});
`
`typescript
localization({
defaultLocale: "pt-BR",
fallbackLocale: "default",
getLocale: async (request) => {
try {
// Use your existing locale detection logic
// This could come from cookies, database, JWT tokens, etc.
const userLocale = await getUserLocale(request);
return userLocale || 'default';
} catch (error) {
console.warn('Error detecting locale:', error);
return 'default'; // Safe fallback
}
}
})
// Example getUserLocale implementation (adapt to your needs)
async function getUserLocale(request: Request): Promise
// Could check user preferences from database, cookies, headers, etc.
// return await db.user.getLocale(userId);
// return getCookieValue(request, 'locale');
// return request.headers.get('x-user-locale');
}
`
`typescript`
localization({
defaultLocale: "fr",
fallbackLocale: "pt-BR", // Can also use built-in locales as fallback
translations: {
"fr": {
USER_NOT_FOUND: "Utilisateur non trouvรฉ",
INVALID_PASSWORD: "Mot de passe invalide",
INVALID_EMAIL: "Email invalide",
SESSION_EXPIRED: "Session expirรฉe"
},
"es": {
USER_NOT_FOUND: "Usuario no encontrado",
INVALID_PASSWORD: "Contraseรฑa invรกlida",
INVALID_EMAIL: "Email invรกlido",
SESSION_EXPIRED: "Sesiรณn expirada"
}
},
});
`typescript`
localization({
defaultLocale: "pt-BR",
translations: {
"pt-BR": {
// Override specific messages
USER_NOT_FOUND: "Usuรกrio nรฃo foi encontrado no sistema",
INVALID_PASSWORD: "A senha fornecida estรก incorreta"
}
}
});
Currently supported languages:
- ๐ง๐ท Portuguese (pt-BR) - โ
Complete
- ๐ต๐น Portuguese (pt-PT) - โ
Complete
- ๐ช๐ธ Spanish (es-ES) - โ
Complete
- ๐ซ๐ท French (fr-FR) - โ
Complete
- ๐ต๐ฑ Polish (pl-PL) - โ
Complete (Thanks @stripsior)
- ๐ฎ๐ฉ Indonesian (id-ID) - โ
Complete (Thanks @finly)
- ๐ฏ๐ต Japanese (ja-JP) - โ
Complete (Thanks @HRTK92)
- ๐ธ๐ฆ Arabic (ar-SA) - โ
Complete (Thanks @mosaleh-dev)
- ๐ฌ๐ท Greek (el-GR) - โ
Complete (Thanks @DomVournias)
- ๐ธ๐ช Swedish (sv-SE) - โ
Complete (Thanks @yamanadamnor)
- ๐ฎ๐น Italian (it-IT) - โ
Complete (Thanks @mattiamalonni)
- ๐ฉ๐ช German (de-DE) - โ
Complete (Thanks @NiklasDah)
- ๐ฉ๐ช German (informal, "du") (de-DE-informal) (default)
- ๐ฉ๐ช German (formal, "Sie") (de-DE-formal)
- ๐จ๐ณ Traditional Chinese (zh-Hant) - โ
Complete (Thanks @MarkLee425)
- ๐จ๐ณ Simplified Chinese (zh-Hans) - โ
Complete (Thanks @MarkLee425)
- ๐ฐ๐ท Korean (ko-KR) - โ
Complete (Thanks @MarkLee425)
- ๐ฎ๐ณ Hindi (hi-HI) - โ
Complete (Thanks @MarkLee425)
- ๐น๐ท Turkish (tr-TR) - โ
Complete (Thanks @furkanczay)
- ๐ณ๐ฑ Dutch (nl-NL) - โ
Complete (Thanks @InvixGG)
- ๐ณ๐ฑ Dutch (informal, "je") (nl-NL-informal) (default)
- ๐ณ๐ฑ Dutch (formal, "u") (nl-NL-formal)
- ๐ฎ๐ท Persian/Farsi (fa-IR) - โ
Complete (Thanks @Yasser5711)
- ๐ท๐บ Russian (ru-RU) - โ
Complete (Thanks @draneone)
- ๐ฎ๐ณ Marathi (mr-MR) - โ
Complete (Thanks @OutOfBoundCats)
- ๐ฉ๐ฐ Danish (da-DK) - โ
Complete (Thanks @BjornFrancke)
- ๐ท๐ด Romanian (ro-RO) - โ
Complete (Thanks @danielavornic)
- ๐ฎ๐ถ Kurdish Sorani (ckb-IQ) - โ
Complete (Thanks @didar-dev)
- ๐ง๐ฉ Bengali (bn-BD) - โ
Complete (Thanks @ktisakib)
- ๐ฆ๐ฟ Azerbaijani (az-AZ) - โ
Complete (Thanks @mehdiasadli)
- ๐ป๐ณ Vietnamese (vi-VN) - โ
Complete (Thanks @trinhvanminh)
- ๐บ๐ฆ Ukrainian (uk-UA) - โ
Complete (Thanks @tarasromil)
The plugin comes with built-in translations for all Better Auth error codes, including:
Core Library:
- User-related errors (USER_NOT_FOUND, USER_ALREADY_EXISTS, etc.)
- Session errors (SESSION_EXPIRED, FAILED_TO_CREATE_SESSION, etc.)
- Authentication errors (INVALID_PASSWORD, INVALID_EMAIL, etc.)
- Password validation (PASSWORD_TOO_SHORT, PASSWORD_TOO_LONG)
- Social authentication errors
- Account management errors
Official Plugins:
- Admin plugin error messages
- Anonymous authentication plugin
- API Key plugin
- Device authorization plugin
- Email OTP plugin
- Generic OAuth plugin
- Have I Been Pwned plugin
- Multi-session plugin
- Organization plugin
- Passkey plugin
- Phone number plugin
- Two-factor authentication plugin
- Username plugin
For a complete and specific list, refer to the Better Auth documentation.
We welcome and appreciate contributions! Help us expand language support by adding new translations.
This repo auto-generates the translations index to avoid PR conflicts when multiple languages are added in parallel.
1. Run the locale creation script:
`bash`
npm run generate:locale
# or
pnpm generate:locale
# or
yarn generate:locale
nl_NL
2. Input your desired locale (e.g., , fr_CA, es_MX)src/translations/index.ts`.
3. The script will automatically:
- Create the main translation file with the correct structure
- Generate plugin-specific translation files with proper types
- Update all necessary LOCALES objects
- Use the correct error code types for each plugin
4. Translate the generated content to match your locale
5. Do not edit or commit
6. Submit your pull request. The index is generated automatically by the build and tests.
The build runs the generator automatically to ensure the index stays up to date.
MIT ยฉ Marcel Losso Forte