Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

LanguageCode
Englishen
Arabicar
Germande
Spanishes
Frenchfr
Japaneseja
Koreanko
Polishpl
Portuguesept
Chinesezh

Supported Services

ServiceStatus
authTranslated error codes are available.
storageTranslated error codes are available.
realtimeTranslated error codes are available.
databasePostgreSQL and PostgREST error codes are available.
functionsThe 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

ServiceTypical source
authsupabase.auth.* calls
storagesupabase.storage.* calls
realtimeRealtime channel and connection status errors
databasePostgreSQL SQLSTATE and PostgREST PGRST error codes
functionsReserved 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:

  1. Target language, selected service, selected code
  2. English, selected service, selected code
  3. Target language unknown_error
  4. 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.

ArgumentDescription
langA 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.

ArgumentDescription
codeThe Supabase error code. Empty, whitespace-only, or undefined values are treated as unknown_error.
serviceOne of auth, storage, realtime, database, or functions.
langOptional 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.

BeforeAfter
jpja
krko
cnzh

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:

  1. Keep every language map structurally aligned with English.
  2. Add or update tests when the public behavior changes.
  3. Keep unknown_error defined for every language.
  4. 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 ar across 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 dist before compiling so stale cn, jp, and kr bundles 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 -> ja for Japanese.
    • kr -> ko for Korean.
    • cn -> zh for Chinese.

Fixes

  • Default language handling: Make translateErrorCode() without a lang argument use currentLanguage.

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 TenantNotFound in 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_error fallback 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.