Svelte component example
Validation
By default, the Svelte 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.<script>
import IntlTelInput from "intl-tel-input/svelte";
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());
};
let number = $state("");
let isValid = $state(false);
let errorCode = $state(null);
let showValidation = $state(false);
let submitted = $state(false);
const invalidMsg = $derived.by(() => {
if (!showValidation || isValid) return null;
return yourCodeToDeriveErrorMessage(number, errorCode);
});
const validMsg = $derived.by(() => {
const showValid = showValidation && isValid && submitted;
return showValid ? `Full number: ${number}` : null;
});
const handleChangeNumber = (newNumber) => {
submitted = false;
number = newNumber;
};
const handleSubmit = (event) => {
event.preventDefault();
showValidation = true;
submitted = true;
};
</script>
<form onsubmit={handleSubmit}>
<label for="phone">Phone number</label>
<IntlTelInput
onChangeNumber={handleChangeNumber}
onChangeValidity={(v) => (isValid = v)}
onChangeErrorCode={(e) => (errorCode = e)}
initialCountry="auto"
separateDialCode={true}
strictMode={true}
strictRejectAnimation={true}
{geoIpLookup}
loadUtils={() => import("intl-tel-input/utils")}
inputProps={{
id: "phone",
onblur: () => (showValidation = true),
}}
/>
<button type="submit">Submit</button>
{#if invalidMsg}
<div class="invalid">{invalidMsg}</div>
{/if}
{#if validMsg}
<div class="valid">{validMsg}</div>
{/if}
</form>