Online Playground
Browse tools

Using libphonenumber-js in Vue and Angular

Validate phone numbers in Vue 3 and Angular with libphonenumber-js. A composable for Vue and a reusable validator for Angular reactive forms.

libphonenumber-js has no framework dependencies, so it fits Vue and Angular equally well. Here is the smallest working integration for each, using each framework's own validation tools.

Vue 3 composable

Return a computed value, so the template updates as the input changes.

js
import { computed } from 'vue'
import { parsePhoneNumberFromString } from 'libphonenumber-js'

export function usePhone(input, country = 'US') {
  const phone = computed(() => parsePhoneNumberFromString(input.value || '', country))
  const isValid = computed(() => !!phone.value && phone.value.isValid())
  const e164 = computed(() => (phone.value ? phone.value.number : ''))
  return { isValid, e164 }
}

Using it in a Vue component

Bind the input with v-model and show the error when a value exists but is not valid.

html
<script setup>
import { ref } from 'vue'
import { usePhone } from './usePhone'
const raw = ref('')
const { isValid, e164 } = usePhone(raw)
</script>

<template>
  <input v-model="raw" type="tel" />
  <p v-if="raw && !isValid">Enter a valid phone number</p>
</template>

Angular validator

Write a ValidatorFn once and attach it to any reactive form control.

ts
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'
import { parsePhoneNumberFromString, CountryCode } from 'libphonenumber-js'

export function phoneValidator(country: CountryCode = 'US'): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    if (!control.value) return null
    const phone = parsePhoneNumberFromString(control.value, country)
    return phone && phone.isValid() ? null : { phone: true }
  }
}

// this.form = this.fb.group({ phone: ['', phoneValidator('GB')] })

Store the E.164 value

Whichever framework you use, save the E.164 form of the number. It is the one format that compares and de-duplicates cleanly. Try the E.164 converter to see the result for your own numbers.

FAQ

Questions people ask

Do I need a wrapper package for Vue or Angular?

No. The library is framework independent. Wrapper components exist for flag dropdowns, but validation needs only the functions shown here.

How do I change the default country at runtime?

Pass the country code as the second argument to parsePhoneNumberFromString. In the examples above, pass a ref or a validator argument that you update when the user changes country.

Does it work with TypeScript?

Yes. The package includes its own type definitions, including the CountryCode type used above.