React component example
Validation
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 Deriving 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.
Demo
allowedNumberTypes option for more information.
JavaScript
geoIpLookup here uses ipapi's limited free tier — for production, pick a paid plan, another provider, or roll your own.yourCodeToDeriveErrorMessage is up to you — see Deriving a user-facing error message for a worked example.import React, { useState } from "react";
import IntlTelInput from "intl-tel-input/react";
import "intl-tel-input/styles";
const geoIpLookup = (success, failure) => {
fetch("https://ipapi.co/json")
.then(res => res.json())
.then(data => success(data.country_code))
.catch(() => failure());
};
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) {
invalidMsg = yourCodeToDeriveErrorMessage(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}
initialCountry="auto"
separateDialCode
strictMode
strictRejectAnimation
geoIpLookup={geoIpLookup}
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;