JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1765
  • Score
    100M100P100Q111977F
  • License MIT

A custom plugin for better-auth that allows you to localize your error messages.

Package Exports

  • better-auth-localization

Readme

Better Auth Localization Plugin

A localization plugin for Better Auth that automatically translates error messages. ezgif-6723e2cdfd4aa9

Features

  • ๐ŸŒ 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

Installation

npm install better-auth-localization
# or
yarn add better-auth-localization
# or
pnpm add better-auth-localization

Quick Start

Basic Usage with Built-in Locale

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
    })
  ]
});

Dynamic Locale Detection

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<string | null> {
  // 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');
}

Custom Translations

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"
    }
  },
});

Overriding Built-in Translations

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"
    }
  }
});

Language Support Status

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)

Built-in Translations

The plugin comes with built-in translations for all Better Auth error codes:

  • 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

For a complete and specific list, refer to the Better Auth documentation.

Contributing

We welcome and appreciate contributions! Help us expand language support by adding new translations.

Adding a new language (no merge conflicts)

This repo auto-generates the translations index to avoid PR conflicts when multiple languages are added in parallel.

  1. Create a new file in src/translations/, for example nl.ts.
  2. Export your translation object and a LOCALES map from that file:
    import type { ErrorCodesType } from "../types";
    
    export const NL_NL = { /* ...all error codes... */ } satisfies ErrorCodesType;
    
    export const LOCALES = {
      "nl-NL": NL_NL,
    } as const;
  3. Do not edit or commit src/translations/index.ts.
  4. 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.

License

MIT ยฉ Marcel Losso Forte