CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-phone-number-input

Telephone number input React component with country selection, validation, and formatting capabilities

Pending
Overview
Eval results
Files

internationalization.mddocs/

Internationalization

Complete internationalization support with locale files for 25+ languages and customizable country/UI labels. The library provides comprehensive localization for country names, UI elements, and supports multiple locale loading patterns.

Capabilities

Locale Files

Pre-built locale files containing translated country names and UI labels.

/**
 * Locale label structure
 * Contains country names and UI element labels
 */
type Labels = Partial<Record<LabelKey, string>>;
type LabelKey = Country | 'ZZ' | 'ext' | 'country' | 'phone';

// Available locale imports
declare const ar: Labels;    // Arabic
declare const ca: Labels;    // Catalan  
declare const cz: Labels;    // Czech
declare const de: Labels;    // German
declare const el: Labels;    // Greek
declare const en: Labels;    // English
declare const es: Labels;    // Spanish
declare const et: Labels;    // Estonian
declare const fi: Labels;    // Finnish
declare const fr: Labels;    // French
declare const he: Labels;    // Hebrew
declare const hy: Labels;    // Armenian
declare const it: Labels;    // Italian
declare const ja: Labels;    // Japanese
declare const ko: Labels;    // Korean
declare const nb: Labels;    // Norwegian Bokmål
declare const nl: Labels;    // Dutch
declare const pl: Labels;    // Polish
declare const pt: Labels;    // Portuguese
declare const pt_BR: Labels; // Portuguese (Brazil)
declare const ru: Labels;    // Russian
declare const sk: Labels;    // Slovak
declare const sv: Labels;    // Swedish
declare const th: Labels;    // Thai
declare const tr: Labels;    // Turkish
declare const ua: Labels;    // Ukrainian
declare const vi: Labels;    // Vietnamese
declare const zh: Labels;    // Chinese

Basic Locale Usage:

import PhoneInput from "react-phone-number-input";
import en from "react-phone-number-input/locale/en.json";
import de from "react-phone-number-input/locale/de.json";
import fr from "react-phone-number-input/locale/fr.json";

// English locale
function EnglishExample() {
  const [value, setValue] = useState();
  return (
    <PhoneInput
      value={value}
      onChange={setValue}
      labels={en}
      defaultCountry="US"
    />
  );
}

// German locale
function GermanExample() {
  const [value, setValue] = useState();
  return (
    <PhoneInput
      value={value}
      onChange={setValue}
      labels={de}
      defaultCountry="DE"
    />
  );
}

// French locale
function FrenchExample() {
  const [value, setValue] = useState();
  return (
    <PhoneInput
      value={value}
      onChange={setValue}
      labels={fr}
      defaultCountry="FR"
    />
  );
}

Locale Import Patterns

Multiple import patterns are supported for different build systems.

// JSON imports (recommended)
import en from "react-phone-number-input/locale/en.json";
import de from "react-phone-number-input/locale/de.json";

// Module imports
import en from "react-phone-number-input/locale/en";
import de from "react-phone-number-input/locale/de";

// CommonJS requires
const en = require("react-phone-number-input/locale/en.json");
const de = require("react-phone-number-input/locale/de.json");

Multiple Locale Support

The locales prop enables automatic locale resolution from browser preferences.

/**
 * Locale property supporting single or multiple locales
 * Automatically selects best match from browser language preferences
 */
type LocaleProperty = string | string[];

interface LocaleProps {
  /** Single locale string or array of locales for automatic selection */
  locales?: LocaleProperty;
  /** Explicit labels object (takes precedence over locales) */
  labels?: Labels;
}

Multi-Locale Examples:

import PhoneInput from "react-phone-number-input";
import "react-phone-number-input/style.css";

// Automatic locale selection from browser
function AutoLocaleExample() {
  const [value, setValue] = useState();
  return (
    <PhoneInput
      value={value}
      onChange={setValue}
      locales={['de', 'fr', 'en']} // Will select best match
      defaultCountry="DE"
    />
  );
}

// Single locale string
function SingleLocaleExample() {
  const [value, setValue] = useState();
  return (
    <PhoneInput
      value={value}
      onChange={setValue}
      locales="es"
      defaultCountry="ES" 
    />
  );
}

Locale Structure

Each locale file contains country names and UI element labels.

/**
 * Locale file structure
 * All entries are optional - missing entries fall back to country codes
 */
interface LocaleStructure {
  // UI element labels
  "ext"?: string;      // Extension label (e.g., "ext.")
  "country"?: string;  // Country selection aria-label
  "phone"?: string;    // Phone input aria-label  
  "ZZ"?: string;       // International option label
  
  // Country name labels (partial list shown)
  "US"?: string;       // "United States"
  "CA"?: string;       // "Canada"  
  "GB"?: string;       // "United Kingdom"
  "DE"?: string;       // "Germany"
  "FR"?: string;       // "France" 
  "JP"?: string;       // "Japan"
  "CN"?: string;       // "China"
  // ... all ~250 country codes supported
}

Example Locale Content:

{
  "ext": "ext.",
  "country": "Phone number country", 
  "phone": "Phone",
  "ZZ": "International",
  "US": "United States",
  "CA": "Canada",
  "GB": "United Kingdom",
  "DE": "Germany",
  "FR": "France",
  "IT": "Italy",
  "ES": "Spain",
  "JP": "Japan",
  "CN": "China",
  "IN": "India",
  "BR": "Brazil",
  "RU": "Russia"
}

Custom Labels

Create custom label objects for specialized use cases or unsupported languages.

/**
 * Custom labels interface
 * Can override any subset of countries and UI elements
 */
interface CustomLabels extends Partial<Labels> {
  [countryCode: string]: string;
}

// Custom label creation
function createCustomLabels(baseLabels: Labels, overrides: Partial<Labels>): Labels {
  return { ...baseLabels, ...overrides };
}

Custom Labels Examples:

import en from "react-phone-number-input/locale/en.json";

// Custom UI labels
const customUILabels: Labels = {
  ...en,
  "country": "Select Country",
  "phone": "Phone Number", 
  "ZZ": "International Number",
  "ext": "extension"
};

// Regional customizations
const regionalLabels: Labels = {
  ...en,
  "US": "USA",
  "GB": "UK", 
  "CN": "Mainland China"
};

// Business-specific labels
const businessLabels: Labels = {
  ...en,
  "US": "United States of America",
  "CA": "Canada (requires verification)",
  "MX": "Mexico (additional fees apply)"
};

function CustomLabelsExample() {
  const [value, setValue] = useState();
  return (
    <PhoneInput
      value={value}
      onChange={setValue}
      labels={customUILabels}
      defaultCountry="US"
    />
  );
}

Locale Loading Strategies

Different strategies for loading and managing locales in applications.

// Static import strategy
import en from "react-phone-number-input/locale/en.json";
import de from "react-phone-number-input/locale/de.json";
import fr from "react-phone-number-input/locale/fr.json";

const localeMap = { en, de, fr };

// Dynamic import strategy
async function loadLocale(locale: string): Promise<Labels> {
  try {
    const module = await import(`react-phone-number-input/locale/${locale}.json`);
    return module.default;
  } catch (error) {
    // Fallback to English
    const fallback = await import("react-phone-number-input/locale/en.json");
    return fallback.default;
  }
}

// Context-based locale management
const LocaleContext = React.createContext<Labels>(en);

Dynamic Locale Loading Examples:

import React, { useState, useEffect } from "react";
import PhoneInput from "react-phone-number-input";

// Dynamic locale loading component
function DynamicLocalePhoneInput({ locale = "en", ...props }) {
  const [labels, setLabels] = useState();
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    loadLocale(locale)
      .then(setLabels)
      .finally(() => setLoading(false));
  }, [locale]);
  
  if (loading) return <div>Loading...</div>;
  
  return (
    <PhoneInput
      {...props}
      labels={labels}
    />
  );
}

// Locale context provider
function LocaleProvider({ locale, children }) {
  const [labels, setLabels] = useState();
  
  useEffect(() => {
    loadLocale(locale).then(setLabels);
  }, [locale]);
  
  return (
    <LocaleContext.Provider value={labels}>
      {children}
    </LocaleContext.Provider>
  );
}

// Hook for using locale context
function useLocale() {
  return useContext(LocaleContext);
}

RTL Language Support

The library supports right-to-left languages through proper labeling.

// RTL language examples
import ar from "react-phone-number-input/locale/ar.json"; // Arabic
import he from "react-phone-number-input/locale/he.json"; // Hebrew

// RTL usage with proper CSS
function RTLExample() {
  const [value, setValue] = useState();
  return (
    <div dir="rtl">
      <PhoneInput
        value={value}
        onChange={setValue}
        labels={ar}
        defaultCountry="SA"
        className="rtl-phone-input"
      />
    </div>
  );
}

Locale Fallback Behavior

The library handles missing locale entries gracefully with fallback behavior.

// Fallback priority order:
// 1. Explicit labels prop
// 2. Resolved locale from locales prop  
// 3. Country code as fallback (e.g., "US" displays as "US")
// 4. Default English labels for UI elements

// Missing country name fallback
const incompleteLocale: Labels = {
  "ext": "ext.",
  "US": "United States",
  // "CA" missing - will display as "CA"
};

// UI element fallbacks
const countryOnlyLocale: Labels = {
  "US": "United States",
  "CA": "Canada"
  // UI elements missing - will use English defaults
};

Fallback Handling Examples:

// Safe locale merging with fallbacks
function mergeWithFallbacks(primaryLocale: Labels, fallbackLocale: Labels): Labels {
  return {
    ...fallbackLocale,
    ...primaryLocale
  };
}

// Locale with guaranteed UI elements
function ensureUILabels(locale: Labels): Labels {
  return {
    ext: "ext.",
    country: "Country", 
    phone: "Phone",
    ZZ: "International",
    ...locale
  };
}

// Usage with fallback
import en from "react-phone-number-input/locale/en.json";
import partialLocale from "./partial-locale.json";

function FallbackExample() {
  const safeLabels = mergeWithFallbacks(partialLocale, en);
  
  return (
    <PhoneInput
      labels={safeLabels}
      // ... other props
    />
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-react-phone-number-input

docs

customization.md

framework-integrations.md

index.md

input-components.md

internationalization.md

phone-input-components.md

utility-functions.md

tile.json