Angular component example

Validation

The Angular component plugs into ReactiveFormsModule as a custom form control and ships with a built-in validator that checks phone numbers by length (sufficient for most use cases — enable usePreciseValidation for stricter matching).

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, the form control's errors["invalidPhone"] contains 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

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 { Component } from "@angular/core";
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms";
import IntlTelInput from "intl-tel-input/angular";
import "intl-tel-input/styles";

@Component({
  selector: "#app",
  template: `
    <form [formGroup]="fg" (ngSubmit)="handleSubmit()">
      <label for="phone">Phone number</label>
      <intl-tel-input
        formControlName="phone"
        [inputAttributes]="{ id: 'phone' }"
        initialCountry="auto"
        [separateDialCode]="true"
        [strictMode]="true"
        [strictRejectAnimation]="true"
        [geoIpLookup]="geoIpLookup"
        [loadUtils]="loadUtils"
      />
      <button type="submit">Submit</button>
      @if (invalidMsg) {
        <div class="invalid-feedback d-block">{{ invalidMsg }}</div>
      }
      @if (validMsg) {
        <div class="valid-feedback d-block">{{ validMsg }}</div>
      }
    </form>
  `,
  standalone: true,
  imports: [IntlTelInput, ReactiveFormsModule],
})
export class AppComponent {
  showValidation = false;
  submitted = false;

  loadUtils = () => import("intl-tel-input/utils");

  geoIpLookup = (success, failure) => {
    fetch("https://ipapi.co/json")
      .then(res => res.json())
      .then(data => success(data.country_code))
      .catch(() => failure());
  };

  fg = new FormGroup({
    phone: new FormControl("", [Validators.required]),
  });

  get phone() {
    return this.fg.get("phone");
  }

  get invalidMsg() {
    if (!this.showValidation || this.phone?.valid) return null;
    if (!this.phone?.value) return "Please enter a number";
    return yourCodeToDeriveErrorMessage(this.phone.errors?.["invalidPhone"] ?? null);
  }

  get validMsg() {
    const showValid =
      this.showValidation && this.phone?.valid && this.submitted;
    return showValid ? `Full number: ${this.phone.value}` : null;
  }

  handleSubmit() {
    this.showValidation = true;
    this.submitted = true;
  }
}