International phone number <input/>
for React.
npm install react-phone-number-input --save
If you're not using a bundler then use a standalone version from a CDN.
The component requires two properties to be passed: value
and onChange(value)
.
import 'react-phone-number-input/style.css'
import PhoneInput from 'react-phone-number-input'
return (
<PhoneInput
placeholder="Enter phone number"
value={ this.state.value }
onChange={ value => this.setState({ value }) } />
)
The value
argument of onChange(value)
function will be the parsed phone number in E.164 format. For example, if a user chooses "United States" and enters (213) 373-4253
in the input field then onChange(value)
will be called with value
being "+12133734253"
.
See the list of all available props
for <PhoneInput/>
. All properties not listed there will be passed through to the phone number <input/>
component.
To set default country pass a country
property. Example: <PhoneInput country="US" .../>
.
To get selected country
pass an onCountryChange(country)
property, or use parsePhoneNumber(value)
function. Example: parsePhoneNumber(value) && parsePhoneNumber(value).country
.
To format value
back to a human-readable phone number use formatPhoneNumber(value)
and formatPhoneNumberIntl(value)
functions.
There's also a "without country select" component available.
import 'react-phone-number-input/style.css'
It is also recommended to set up something like a postcss-loader
with a CSS autoprefixer for supporting old web browsers.
Get the style.css
file from this package, optionally process it with a CSS autoprefixer for supporting old web browsers, and then include the CSS file on a page.
<head>
<link rel="stylesheet" href="/css/react-phone-number-input/style.css"/>
</head>
Or include the style.css
file directly from a CDN.
This package exports several utility functions.
Formats value
as a "local" phone number.
import { formatPhoneNumber } from 'react-phone-number-input'
formatPhoneNumber('+12133734253') === '(213) 373-4253'
Formats value
as an "international" phone number.
import { formatPhoneNumberIntl } from 'react-phone-number-input'
formatPhoneNumberIntl('+12133734253') === '+1 213 373 4253'
Validates a phone number value
.
import { isValidPhoneNumber } from 'react-phone-number-input'
isValidPhoneNumber('+12133734253') === true
By default the component uses min
"metadata" which results in less strict validation compared to max
or mobile
.
I personally wouldn't use strict phone number validation at all because telephone numbering plans constantly evolve and validation rules do change over time which means isValidPhoneNumber()
function may become outdated if a website isn't re-deployed regularly. Still, some people wanted this feature, so it's included.
Parses a PhoneNumber
object from a string
. This is simply an alias for parsePhoneNumberFromString()
from libphonenumber-js
. Can be used to get country
from value
.
import { parsePhoneNumber } from 'react-phone-number-input'
const phoneNumber = parsePhoneNumber('+12133734253')
if (phoneNumber) {
phoneNumber.country === 'US'
}
This is simply an alias for getCountryCallingCode()
from libphonenumber-js
.
import { getCountryCallingCode } from 'react-phone-number-input'
getCountryCallingCode('US') === '1'
Including all country flags in the code in SVG format would be the best way to go but turns out they take an extra 550 kB when gzipped. That's the reason why all country flags are included as <img src="..."/>
from flag-icon-css
repo GitHub pages (can be overridden via flagsPath
property).
To include all country flags in code in SVG format:
import PhoneInput from 'react-phone-number-input'
import flags from 'react-phone-number-input/flags'
<PhoneInput flags={flags} .../>
Language translations can be applied using the labels
property. This component comes pre-packaged with several translations (submit pull requests for adding new language translations).
The labels
format is:
{
// Country `<select/>` `aria-label`.
"country": "Country",
// Phone number `<input/>` `aria-label`.
// (not set by default)
"phone": "Phone",
// Phone number "extension" `aria-label`.
// (not set by default)
"ext": "ext.",
// Country names.
"AB": "Abkhazia",
"AC": "Ascension Island",
...,
"ZZ": "International"
}
An example of using translated labels
:
import ru from 'react-phone-number-input/locale/ru'
<PhoneInput ... labels={ru}/>
By default, the country <select/>
has aria-label
set to labels.country
which is "Country"
for the default labels
. When passing labels
for other languages the default aria-label
of the country <select/>
will be translated too. To set a custom aria-label
on the country <select/>
pass a countrySelectAriaLabel
property to <PhoneInput/>
.
The phone <input/>
aria-label
is not set automatically to labels.phone
for legacy reasons. To set it manually pass an aria-label
property to <PhoneInput/>
.
This component uses libphonenumber-js
which requires choosing a "metadata" set to be used, "metadata" being a list of phone number parsing and formatting rules for all countries. The complete list of rules is huge, so libphonenumber-js
provides a way to optimize bundle size by choosing between max
, min
, mobile
and custom metadata:
-
max
— The complete metadata set, is about140 kilobytes
in size (libphonenumber-js/metadata.full.json
). -
min
— (default) The smallest metadata set, is about75 kilobytes
in size (libphonenumber-js/metadata.min.json
). Doesn't contain regular expressions for advanced phone number validation. Some simple phone number validation still works (basic length check, etc), it's just that it's loose compared to the "advanced" validation (not so strict). Choose this when not usingisValidPhoneNumber(value)
function. -
mobile
— The complete metadata set for dealing with mobile numbers only, is about105 kilobytes
in size (libphonenumber-js/metadata.mobile.json
). Choose this when usingisValidPhoneNumber(value)
function, but only dealing with mobile phone numbers.
To use a particular metadata set import the component from the relevant sub-package: react-phone-number-input/max
, react-phone-number-input/min
or react-phone-number-input/mobile
.
Importing the component directly from react-phone-number-input
results in using the min
metadata which means loose (non-strict) phone number validation.
Sometimes (rarely) not all countries are needed and in those cases the developers may want to generate their own "custom" metadata set. For those cases there's react-phone-number-input/core
sub-package which doesn't come pre-wired with any default metadata and instead accepts the metadata as a property.
If you think that the phone number parsing/formatting/validation engine malfunctions for a particular phone number then follow the bug reporting instructions in libphonenumber-js
repo. Otherwise report issues in this repo.
Make sure to put a <PhoneInput/>
into a <form/>
otherwise web-browser's "autocomplete" feature may not be working: a user will be selecting his phone number from the list but nothing will be happening.
Some people prefer just a phone number input component without country <select/>
.
import PhoneInput from 'react-phone-number-input/input'
class Example extends Component {
state = {
value: ''
}
render() {
// If `country` property is not passed
// then "International" format is used.
return (
<PhoneInput
country="US"
value={ this.state.value }
onChange={ value => this.setState({ value }) } />
)
}
}
Receives properties:
country: string?
— If nocountry
is specified then the phone number can only be input in international format.value: string?
— Phone numbervalue
. Examples:undefined
,"+12133734253"
.onChange(value: string?)
— Updates thevalue
.inputComponent: component?
— A custom<input/>
component can be passed.
For those who want to pass custom metadata
there's react-phone-number-input/input-core
subpackage.
One can supply their own country <select/>
component in case the native one doesn't fit the app. See countrySelectComponent
property.
For example, one may choose react-responsive-ui
's <Select/>
component over the native country <select/>
.
import 'react-phone-number-input/style.css'
// Requires "CSS custom properties" support.
// For Internet Explorer use PostCSS with "CSS custom properties" plugin.
import 'react-responsive-ui/style.css'
// A `<PhoneInput/>` with custom `countrySelectComponent`.
import PhoneInput from 'react-phone-number-input/react-responsive-ui'
return (
<PhoneInput
placeholder="Enter phone number"
value={ this.state.phone }
onChange={ phone => this.setState({ phone }) } />
)
There's nothing special about a phone number extension input: it doesn't need any formatting, it can just be a simple <input type="number"/>
. Still, some users kept asking for a phone number extension input feature. So I added a basic phone number extension input support. It can be activated by passing ext
property (a React.Element
, see the demo).
import React, { Component } from 'react'
import { Field, reduxForm } from 'redux-form'
import PhoneInput from 'react-phone-number-input'
class Form extends Component {
render() {
const ext = (
<input
value={ ... }
onChange={ ... }
type="number"
noValidate />
)
return (
<form onSubmit={ ... }>
<PhoneInput
value={ ... }
onChange={ ... }
ext={ ext } />
<button type="submit">
Submit
</button>
</form>
);
}
}
In a real-world application the ext
property is most likely gonna be a "form field", e.g. an easy-react-form
<Field/>
, or a redux-form
<Field/>
, or a react-final-form
<Field/>
.
Phone number extension input will appear to the right of the phone number input. One can always skip using the ext
property and add a completely separate form field for phone number extension input instead.
{ number, ext }
object can be converted to an RFC3966 string for storing it in a database.
import { formatRFC3966 } from 'react-phone-number-input'
formatRFC3966({ number: '+12133734253', ext: '123' })
// 'tel:+12133734253;ext=123'
Use the accompanying parseRFC3966()
function to convert an RFC3966 string into an object having shape { number, ext }
.
import { parseRFC3966 } from 'react-phone-number-input'
parseRFC3966('tel:+12133734253;ext=123')
// { number: '+12133734253', ext: '123' }
The <PhoneInput/>
component accepts some customization properties:
-
metadata
— Customlibphonenumber-js
"metadata". -
labels
— Custom translation (including country names). -
internationalIcon
— Custom "International" icon. -
numberInputComponent
— Custom phone number<input/>
component. -
countrySelectComponent
— Custom country<select/>
component.
import PhoneInput from 'react-phone-number-input/min'
import metadata from 'libphonenumber-js/metadata.min.json'
import labels from 'react-phone-number-input/locale/ru'
import InternationalIcon from 'react-phone-number-input/international-icon'
<PhoneInput
numberInputComponent={...}
countrySelectComponent={...}
labels={labels}
metadata={metadata}
internationalIcon={InternationalIcon}/>
All these customization properties have their default values. If some of those default values are not used, and the developer wants to reduce the bundle size a bit, then they can use the /core
export instead of the default export to import a <PhoneInput/>
component which doesn't include any of the default customization properties: in this case all customization properties must be passed.
import PhoneInput from 'react-phone-number-input/core'
React component for the country select. See CountrySelectNative and CountrySelectReactResponsiveUI for an example.
Receives properties:
name : string?
— HTMLname
attribute.value : string?
— The currently selected country code.onChange(value : string?)
— Updates thevalue
.onFocus()
— Is used to toggle the--focus
CSS class.onBlur()
— Is used to toggle the--focus
CSS class.options : object[]
— The list of all selectable countries (including "International") each being an object of shape{ value : string?, label : string, icon : React.Component }
.disabled : boolean?
— HTMLdisabled
attribute.tabIndex : (number|string)?
— HTMLtabIndex
attribute.className : string
— CSS class name.
React component for the phone number input field. Is "input"
by default meaning that it renders a standard DOM <input/>
.
Receives properties:
value: string
— The formattedvalue
.onChange(event: Event)
— Updates the formattedvalue
fromevent.target.value
.onFocus()
— Is used to toggle the--focus
CSS class.onBlur(event: Event)
— Is used to toggle the--focus
CSS class.- Other properties like
type="tel"
orautoComplete="tel"
that should be passed through to the DOM<input/>
.
Must also either use React.forwardRef()
to "forward" ref
to the <input/>
or implement .focus()
method.
One can use any npm CDN service, e.g. unpkg.com or jsdelivr.net
<!-- `libphonenumber-js` (is used internally by `react-phone-number-input`). -->
<script src="https://unpkg.com/[email protected]/bundle/libphonenumber-js.min.js"></script>
<!-- Either `react-phone-number-input` with "native" country `<select/>`. -->
<script src="https://unpkg.com/[email protected]/bundle/react-phone-number-input-native.js"></script>
<!-- or `react-phone-number-input` with "native" country `<select/>` (with "max" metadata). -->
<script src="https://unpkg.com/[email protected]/bundle/react-phone-number-input-native-max.js"></script>
<!-- or `react-phone-number-input` with "native" country `<select/>` (with "mobile" metadata). -->
<script src="https://unpkg.com/[email protected]/bundle/react-phone-number-input-native-mobile.js"></script>
<!-- Or `react-phone-number-input` with `react-responsive-ui` `<Select/>`. -->
<script src="https://unpkg.com/[email protected]/bundle/react-phone-number-input-react-responsive-ui.js"></script>
<!-- Or `react-phone-number-input` without country `<select/>`. -->
<script src="https://unpkg.com/[email protected]/bundle/react-phone-number-input-no-country-select.js"></script>
<!-- Styles for the component. -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/bundle/style.css"/>
<!-- Styles for `react-responsive-ui` `<Select/> -->
<!-- (only if `react-responsive-ui` `<Select/>` is used). -->
<link rel="stylesheet" href="https://unpkg.com/react-responsive-ui@^0.14.0/style.css"/>
<script>
var PhoneInput = window['react-phone-number-input']
</script>
React Responsive UI component library.