React component example

Validation

Overview

By default, the React component validates phone numbers by length (sufficient for most use cases — enable usePreciseValidation for stricter matching), surfacing the result through three callback props: onChangeNumber, onChangeValidity, and onChangeErrorCode.

Validation respects the allowedNumberTypes option, which is set to ["MOBILE", "FIXED_LINE"] by default, meaning it will only consider those types of numbers as valid.

When a number fails validation, onChangeErrorCode fires with the error code, which you can then map to your own custom error message — see Show a user-facing error message.

Note: the red/green styling and warning/success icons are not part of the component — in this example they come from Bootstrap form validation.

Note: the toast shown when input is rejected isn't part of the library — see the onStrictReject callback docs for an example of how to wire one up yourself.

Demo

JavaScript

initialCountryLookup here uses ipapi's free tier. For production, swap for a paid plan or alternative - see docs.
getErrorMessage is up to you - see a worked example.
import React, { useState } from "react";
import IntlTelInput from "@intl-tel-input/react";
import "intl-tel-input/styles";

const initialCountryLookup = async () => {
  const res = await fetch("https://ipapi.co/json");
  const data = await res.json();
  return data.country_code;
};

const App = () => {
  const [number, setNumber] = useState("");
  const [isValid, setIsValid] = useState(false);
  const [errorCode, setErrorCode] = useState(null);
  const [showValidation, setShowValidation] = useState(false);
  const [submitted, setSubmitted] = useState(false);

  let invalidMsg = null;
  if (showValidation && !isValid) {
    // your code here to map the errorCode to a user-facing message
    invalidMsg = getErrorMessage(number, errorCode);
  }

  const validMsg = showValidation && isValid && submitted
    ? `Full number: ${number}`
    : null;

  const handleChangeNumber = (newNumber) => {
    setSubmitted(false);
    setNumber(newNumber);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setShowValidation(true);
    setSubmitted(true);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="phone">Phone number</label>
      <IntlTelInput
        onChangeNumber={handleChangeNumber}
        onChangeValidity={setIsValid}
        onChangeErrorCode={setErrorCode}
        initialCountryLookup={initialCountryLookup}
        loadUtils={() => import("intl-tel-input/utils")}
        inputProps={{
          id: "phone",
          onBlur: () => setShowValidation(true),
        }}
      />
      <button type="submit">Submit</button>
      {invalidMsg && (
        <div className="invalid">{invalidMsg}</div>
      )}
      {validMsg && (
        <div className="valid">{validMsg}</div>
      )}
    </form>
  );
};
export default App;