Better Auth Localization Plugin
The `better-auth-localization` plugin provides comprehensive internationalization (i18n) capabilities for error messages generated by the `better-auth` library and its official plugins. It aims to offer a seamless developer experience by automatically translating error messages without requiring changes to application logic. Currently at v3.0.0, this package regularly releases patch updates for new language support and minor fixes, with major versions tied to significant updates in its peer dependency, `better-auth`. Key features include multi-language support, automatic error message translation, full TypeScript type safety with autocomplete for custom translations, a robust fallback system for missing translations, flexible locale detection strategies (e.g., from headers, cookies, or database), and zero runtime overhead as translations are bundled at build time. It differentiates itself by tightly integrating with the `better-auth` ecosystem to provide a specialized localization solution.
Common errors
-
TypeError: betterAuth is not a function
cause Attempting to use `betterAuth` as a default import instead of a named import.fixChange `import betterAuth from 'better-auth';` to `import { betterAuth } from 'better-auth';` -
Error: Peer dependency better-auth@^1.5.0 not met.
cause Your installed `better-auth` version does not satisfy the `better-auth-localization` v3.x requirement.fixUpgrade your `better-auth` package to version `1.5.0` or higher using `npm install better-auth@latest` or `pnpm add better-auth@latest`. -
Error: USER_NOT_FOUND (or similar untranslated error message)
cause Localization plugin is not configured or activated, or the requested locale is not found and no fallback is provided.fixVerify that `localization` is included in the `betterAuth` plugins array. Ensure `defaultLocale` and `fallbackLocale` are correctly set, or implement a `getLocale` function that returns a supported locale. -
Type 'Request' is not assignable to type 'Request'.
cause Potential type mismatch for the `Request` object passed to `getLocale` when integrating with specific web frameworks or custom server setups.fixEnsure the `Request` object provided to `getLocale` matches the expected `Request` interface (e.g., from `@types/node` or a specific web framework's types). You may need to cast the request object or adjust your type definitions.
Warnings
- breaking Version 3.0.0 of `better-auth-localization` requires `better-auth` v1.5.0 or newer. Ensure your core `better-auth` dependency is updated to avoid compatibility issues.
- gotcha The `getLocale` option for dynamic locale detection requires manual implementation. The plugin does not automatically infer locale from user sessions or requests; you must provide a function to extract it from `Request` headers, cookies, or other sources.
- gotcha Prior to v2.1.6, providing custom translations for a specific error code would completely override all other translations for that language. Since v2.1.6, custom translations are merged, allowing partial overrides while retaining built-in translations for unspecified error codes.
- gotcha The `localization` plugin must be included in the `plugins` array of your `betterAuth` configuration. Forgetting to register it will result in no localization being applied to error messages.
Install
-
npm install better-auth-localization -
yarn add better-auth-localization -
pnpm add better-auth-localization
Imports
- localization
const localization = require('better-auth-localization');import { localization } from 'better-auth-localization'; - LocalizationPluginOptions
import { LocalizationPluginOptions } from 'better-auth-localization';import type { LocalizationPluginOptions } from 'better-auth-localization'; - betterAuth
import betterAuth from 'better-auth';
import { betterAuth } from 'better-auth';
Quickstart
import { betterAuth } from 'better-auth';
import { localization } from 'better-auth-localization';
// Example: Simulate a basic better-auth config
const exampleConfig = {
secret: process.env.AUTH_SECRET ?? 'super-secret-development-key',
cookie: {
secure: process.env.NODE_ENV === 'production'
}
};
export const auth = betterAuth({
...exampleConfig,
plugins: [
localization({
defaultLocale: 'pt-BR', // Use built-in Portuguese translations
fallbackLocale: 'default', // Fallback to English
// For dynamic locale detection, you would add a getLocale function here:
// getLocale: async (req) => {
// // Imagine reading locale from a cookie or header
// const cookieHeader = (req as any)?.headers?.get("cookie");
// const cookies = cookieHeader ? Object.fromEntries(cookieHeader.split('; ').map(c => c.split('='))) : {};
// return cookies.locale ?? 'default';
// }
})
]
});
// To demonstrate usage (this part is illustrative and not part of the quickstart plugin setup):
// try {
// // Simulate an authentication call that might throw an error
// // const user = await auth.signIn('test@example.com', 'wrong-password');
// } catch (error: any) {
// console.log('Localized error:', error.message); // Should output translated message
// }