About
supabase-error-translator-js maps Supabase error codes to user-facing messages in
multiple languages. It is useful when your app receives technical error codes from
Supabase Auth, Storage, Realtime, or PostgREST and needs a localized message for the UI.
The package does not call Supabase and does not depend on @supabase/supabase-js. It is a
small translation registry plus a few helper functions.
This project is maintained independently. It is not officially associated with, endorsed by, or affiliated with Supabase.
Supported Languages
| Language | Code |
|---|---|
| English | en |
| Arabic | ar |
| German | de |
| Spanish | es |
| French | fr |
| Japanese | ja |
| Korean | ko |
| Polish | pl |
| Portuguese | pt |
| Chinese | zh |
Supported Services
| Service | Status |
|---|---|
auth | Translated error codes are available. |
storage | Translated error codes are available. |
realtime | Translated error codes are available. |
database | PostgreSQL and PostgREST error codes are available. |
functions | The service is accepted by the API, but translations are currently empty. Unknown fallback text is returned. |
What The Package Returns
The package returns strings, not rich error objects. It intentionally keeps the public API simple so callers can use the result in React, Next.js, Node.js, or any browser-bundled application.
Installation
Requirements
supabase-error-translator-js requires Node.js 18 or newer when used in a Node.js
environment. Browser apps can consume it through their normal bundler.
Package Manager
Install from npm:
npm install supabase-error-translator-js
With pnpm:
pnpm add supabase-error-translator-js
With yarn:
yarn add supabase-error-translator-js
Import
import { translateErrorCode } from 'supabase-error-translator-js';
The package ships JavaScript and TypeScript declaration files from dist/.
Quick Start
Translate a Supabase Auth error code:
import { translateErrorCode } from 'supabase-error-translator-js';
const message = translateErrorCode('invalid_credentials', 'auth', 'de');
console.log(message);
Set a process-wide or browser-session default language:
import { setLanguage, translateErrorCode } from 'supabase-error-translator-js';
setLanguage('es');
const message = translateErrorCode('email_not_confirmed', 'auth');
Use browser language detection:
import { setLanguage } from 'supabase-error-translator-js';
setLanguage('auto');
For server-side rendering or request handlers, prefer passing the language to
translateErrorCode() for each call:
import { translateErrorCode, type SupportedLanguage } from 'supabase-error-translator-js';
export function translateSupabaseError(code: string | undefined, userLanguage: SupportedLanguage) {
return translateErrorCode(code, 'auth', userLanguage);
}
Language Handling
Supported Codes
The package uses ISO 639-1 language codes:
import { getSupportedLanguages } from 'supabase-error-translator-js';
console.log(getSupportedLanguages());
// ['en', 'ar', 'de', 'es', 'fr', 'ja', 'ko', 'pl', 'pt', 'zh']
Default Language
The default language is English:
import { getCurrentLanguage } from 'supabase-error-translator-js';
console.log(getCurrentLanguage());
// 'en'
Call setLanguage() to change the default:
import { setLanguage } from 'supabase-error-translator-js';
setLanguage('fr');
Unsupported values fall back to English.
Browser Detection
Pass auto to use the primary browser language from navigator.language:
import { setLanguage } from 'supabase-error-translator-js';
setLanguage('auto');
For example, de-DE resolves to de. Unsupported browser languages fall back to en.
When navigator is unavailable, detection also falls back to en.
Per-Call Language Override
The third argument to translateErrorCode() overrides the current default without
mutating it:
import { getCurrentLanguage, translateErrorCode } from 'supabase-error-translator-js';
const message = translateErrorCode('phone_exists', 'auth', 'pt');
console.log(getCurrentLanguage());
// Still whatever was previously set.
This is the safer pattern for multi-user server code because setLanguage() stores
module-level state.
Services And Fallbacks
Supabase can reuse the same error code string in different services. Because of that,
translateErrorCode() requires a service argument.
import { translateErrorCode } from 'supabase-error-translator-js';
translateErrorCode('TenantNotFound', 'storage', 'en');
translateErrorCode('TenantNotFound', 'realtime', 'en');
Services
| Service | Typical source |
|---|---|
auth | supabase.auth.* calls |
storage | supabase.storage.* calls |
realtime | Realtime channel and connection status errors |
database | PostgreSQL SQLSTATE and PostgREST PGRST error codes |
functions | Reserved for Supabase Edge Functions. Translation maps are currently empty. |
Fallback Chain
Empty, whitespace-only, or missing codes are normalized to unknown_error.
For other codes, the lookup order is:
- Target language, selected service, selected code
- English, selected service, selected code
- Target language
unknown_error - English
unknown_error
Unsupported service names are handled defensively at runtime and return the localized unknown-error fallback.
Unknown Codes
import { translateErrorCode } from 'supabase-error-translator-js';
const message = translateErrorCode('not_a_real_code', 'auth', 'de');
This returns the German unknown-error message if it exists, otherwise the English unknown-error message.
API Reference
setLanguage(lang)
function setLanguage(lang: SupportedLanguage | 'auto'): void;
Sets the module-level default language.
| Argument | Description |
|---|---|
lang | A supported language code or auto. Unsupported values fall back to en at runtime. |
Use per-call language overrides instead of setLanguage() in request-scoped server code.
translateErrorCode(code, service, lang?)
function translateErrorCode(
code: string | undefined,
service: ErrorService,
lang?: SupportedLanguage | 'auto',
): string;
Returns a translated string for a Supabase error code.
| Argument | Description |
|---|---|
code | The Supabase error code. Empty, whitespace-only, or undefined values are treated as unknown_error. |
service | One of auth, storage, realtime, database, or functions. |
lang | Optional per-call language override. auto uses browser detection. |
getCurrentLanguage()
function getCurrentLanguage(): SupportedLanguage;
Returns the current module-level default language.
getSupportedLanguages()
function getSupportedLanguages(): SupportedLanguage[];
Returns a copy of the supported language-code list.
isSupportedLanguage(lang)
function isSupportedLanguage(lang: string): lang is SupportedLanguage;
Runtime guard for supported language codes.
isSupportedService(service)
function isSupportedService(service: string): service is ErrorService;
Runtime guard for supported service names.
Constants And Types
import {
SUPPORTED_LANGUAGES,
SUPPORTED_SERVICES,
type ErrorService,
type SupportedLanguage,
type TranslationStructure,
} from 'supabase-error-translator-js';
Examples
Supabase Auth
import { useState, type FormEvent } from 'react';
import { translateErrorCode, type SupportedLanguage } from 'supabase-error-translator-js';
import { supabase } from './supabaseClient';
type Props = {
language: SupportedLanguage;
};
export function SignInForm({ language }: Props) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [errorMessage, setErrorMessage] = useState<string | null>(null);
async function signIn(event: FormEvent) {
event.preventDefault();
setErrorMessage(null);
const { error } = await supabase.auth.signInWithPassword({ email, password });
if (error) {
setErrorMessage(translateErrorCode(error.code, 'auth', language));
}
}
return (
<form onSubmit={signIn}>
{errorMessage && <p role="alert">{errorMessage}</p>}
<input value={email} onChange={(event) => setEmail(event.target.value)} />
<input
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
/>
<button type="submit">Sign in</button>
</form>
);
}
Database And PostgREST
Database errors often expose SQLSTATE codes such as 23505 or PostgREST codes such as
PGRST204.
import { translateErrorCode } from 'supabase-error-translator-js';
import { supabase } from './supabaseClient';
const { error } = await supabase.from('profiles').insert({
username: 'existing-user',
});
if (error) {
const message = translateErrorCode(error.code, 'database', 'en');
console.log(message);
}
Storage
import { translateErrorCode } from 'supabase-error-translator-js';
import { supabase } from './supabaseClient';
async function uploadAvatar(file: File) {
const { error } = await supabase.storage.from('avatars').upload('public/avatar.png', file);
if (error) {
const message = translateErrorCode(error.code, 'storage', 'es');
console.log(message);
}
}
Realtime
Realtime status callbacks do not always include a structured error. Use
unknown_error when no code is present.
import { translateErrorCode } from 'supabase-error-translator-js';
import { supabase } from './supabaseClient';
const channel = supabase.channel('room').subscribe((status, error) => {
if (status === 'CHANNEL_ERROR') {
const message = translateErrorCode(error?.code, 'realtime', 'fr');
console.log(message);
}
});
Runtime Guards
import {
isSupportedLanguage,
isSupportedService,
translateErrorCode,
} from 'supabase-error-translator-js';
const language = isSupportedLanguage(userLanguage) ? userLanguage : 'en';
const service = isSupportedService(serviceFromLog) ? serviceFromLog : 'auth';
const message = translateErrorCode(codeFromLog, service, language);
Migration Guide
From v2 To v3
Version 3 uses ISO 639-1 language codes for Japanese, Korean, and Chinese.
| Before | After |
|---|---|
jp | ja |
kr | ko |
cn | zh |
Update calls like this:
import { setLanguage } from 'supabase-error-translator-js';
setLanguage('ja');
setLanguage('ko');
setLanguage('zh');
translateErrorCode() without a lang argument now uses the language set by
setLanguage() instead of always trying browser detection.
From v1 To v2
Version 2 added service-specific translation maps. translateErrorCode() now requires a
service argument.
import { translateErrorCode } from 'supabase-error-translator-js';
// v1
translateErrorCode('invalid_credentials');
// v2 and newer
translateErrorCode('invalid_credentials', 'auth');
Choose the service from the Supabase API that produced the error.
Contributing
See the repository contribution guide for the full workflow.
Local Setup
pnpm install
Checks
pnpm run lint
pnpm run type-check
pnpm test
pnpm run build
pnpm run prettier:check
Translation Changes
When adding or changing translations:
- Keep every language map structurally aligned with English.
- Add or update tests when the public behavior changes.
- Keep
unknown_errordefined for every language. - Document new public behavior in this manual.
The test suite checks that every supported language defines the same service keys as the English translation map.
Documentation
Build the mdBook locally:
mdbook build docs
Serve it locally while editing:
mdbook serve docs
Changelog
All notable changes to this project will be documented in this file.
[3.1.0] - 2026-05-28 Changes
Features
- Arabic translations (#22, @ahmedalmnsour): Add
aracross Auth, Realtime, Storage, and Database. - Language and service guards (#21, @srothgan): Export supported-language and supported-service helpers.
Improvements
- Translation registry (#21, @srothgan): Derive supported languages from one registry.
- Fallback handling (#21, @srothgan): Validate service names at runtime and expand fallback coverage.
Documentation
- mdBook manual (#23, @srothgan): Add the
docs/manual and GitHub Pages workflow. - Focused README (#23, @srothgan): Move extended usage, API, examples, and migration material into docs.
- Contributor workflow (@srothgan): Clarify the external-contributor workflow.
CI and Dependencies
- Audit cleanup (#11, @srothgan): Resolve 24 advisories and add Node/pnpm project foundations.
- Tooling refresh (#12, @srothgan): Upgrade to ESLint 10, TypeScript 6, rimraf 6, and Vitest.
- CI matrices (#13, @srothgan): Refresh Actions and test/build on Node 20, 22, and 24.
- Release automation (#14, #20, @srothgan): Add trusted npm publishing, GitHub Releases, Knip, and audit gates.
- Repository polish (#19, @srothgan): Add issue/PR templates, CodeQL, and README workflow badges.
Compatibility
- Additive release (#21, #22, #23): Keep existing language codes, service keys, and fallback behavior compatible.
[3.0.1] - 2025-08-30 Changes
Fixes
- Build cleanup: Clean
distbefore compiling so stalecn,jp, andkrbundles are removed after the ISO-code migration. - API stability: No API changes.
[3.0.0] - 2025-08-29 Changes
Breaking Changes
- ISO language codes: Replace legacy language codes with ISO 639-1 codes:
jp->jafor Japanese.kr->kofor Korean.cn->zhfor Chinese.
Fixes
- Default language handling: Make
translateErrorCode()without alangargument usecurrentLanguage.
Documentation
- Migration guidance: Update examples and API references for the new language codes.
Migration Guide
Update language-code usage:
// Before v3.0.0
setLanguage('jp');
setLanguage('kr');
setLanguage('cn');
// v3.0.0 and newer
setLanguage('ja');
setLanguage('ko');
setLanguage('zh');
[2.2.1] - 2025-06-01 Changes
Documentation
- Contributor guide (#8): Rename and refresh the contribution guide.
Fixes
- Translation polish (#8): Clean up wording across language helpers and translation maps.
[2.2.0] - 2025-05-27 Changes
Features
- Expanded language support: Add Japanese, Korean, Polish, Portuguese, and Chinese translations.
- Global coverage: Bring supported languages to 9.
Documentation
- Language examples: Update the README language table, auto-detection examples, and API notes.
[2.1.0] - 2025-05-09 Changes
Features
- Database errors: Add PostgreSQL SQLSTATE and PostgREST error-code translations.
- Constraint guidance: Add user-friendly messages for common database constraints and query failures.
[2.0.1] - 2025-05-04 Changes
Fixes
- npm package build: Fix the npm build issue in the 2.0 release line.
[2.0.0] - 2025-05-04 Changes
Breaking Changes
- Service-scoped translations: Organize translations by Supabase service.
- API signature: Require a service argument in
translateErrorCode().
// Before v2.0.0
translateErrorCode(code, lang);
// v2.0.0 and newer
translateErrorCode(code, service, lang);
Features
- Storage errors: Add Supabase Storage error-code translations.
- Overlapping error codes: Resolve same-code cases by service context, such as
TenantNotFoundin Storage versus Realtime. - Type safety: Add stronger service and translation-structure types.
[1.1.1] - 2025-05-03 Changes
Documentation
- README cleanup: Apply small README fixes.
[1.1.0] - 2025-05-03 Changes
Features
- Usage examples: Expand README examples.
- Project docs: Add Code of Conduct and contribution guidance.
Fixes
- Unknown-code handling: Improve
unknown_errorfallback behavior. - Empty input handling: Handle undefined and empty error codes.
[1.0.1] - 2025-05-01 Changes
Initial Release
- Auth translations: Add initial English, German, French, and Spanish authentication translations.