React country and state fields that detect users' geolocation
Tags: react, javascript, node, webdev
Published: 2022-10-24 10:40:02

Many React applications require users to select their countries and states during the setup process. It can be very annoying for the users to select a country out of hundreds of countries in a long list. It will be ideal if the country and state fields are able to detect the users’ countries and states and pre-fill them.

There are two possible ways to achieve this goal: Geolocation API or IP geolocation detection. Geolocation API shows a popup that is annoying and scary at the same time, and a lot of users would simply block it.

![Geolocation API popup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndzpujewhm3i9p9u3ua1.png)

The challenge for the IP geolocation solution is that JavaScript in browsers isn’t able to access the users’ IP addresses. However, with the help of a server-side API, this can be resolved. This article will cover how to use a React country and state field package that comes with IP geolocation detection without going into the weeds.

## Installation

The package we use is called `react-country-state-fields` and to install it, simply run:

```
npm i react-country-state-fields
```

The package uses Material UI but if you don’t use Material UI, it will still function without issues.

## Usage of the components

There are three components in the package:

- VisitorAPIComponents - this is a invisible component that calls the server-side API to detect the user’s IP geolocation and set the default values of the country and state fields based on the geolocation.
- CountryField - this is the country field component that is able to take the geolocation data and set the country automatically. It’s also a user-friendly country field that allows users to pick or type in their countries.
- StateField - this is the state field component similar to the country field component, but for the state level. If the country’s states are listed in the package’s JSON file `countries.json`, the field will have a list of the states for users to pick, otherwise, it will just be an open text field that users can input their states.

It is very simple to put the components into action as in the example code below.

```jsx
import { CountryField, StateField, VisitorAPIComponents } from 'react-country-state-fields';
import React, { useState } from 'react';

export const MyForm = () => {
  const [country, setCountry] = useState({code: "", label: ""}); // the selected country
  const [state, setState] = useState({code: "", label: ""}); // the selected state
  const visitorApiPrjectId = ""; // assign your project ID here

  return(
    <VisitorAPIComponents projectId={visitorApiPrjectId} handleCountryChange={(countryObj) => setCountry(countryObj)} handleStateChange={(stateObj) => setState(stateObj)}>
      <CountryField label="Country/Territory"></CountryField>
      <StateField label="State/Province"></StateField>
    </VisitorAPIComponents>
  );
}
```

The `country` and `state` React states will contain two properties called `code` and `label` when API detects the user’s geolocation or the user change the field values. The `code` is the ISO code of the country or state, such as “US” for the United States in the `country` state and “NY” for New York in the `state` state. This is a screenshot when I load the fields in my testing React application.

![React Country and State Fields](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qavg2idk014u5kfpxpvf.png)

You can use them as the following code example:

```jsx
import { CountryField, StateField, VisitorAPIComponents } from 'react-country-state-fields';
import React, { useState } from 'react';

export const MyForm = () => {
  const [country, setCountry] = useState({code: "", label: ""}); // the selected country
  const [state, setState] = useState({code: "", label: ""}); // the selected state
  const visitorApiPrjectId = ""; // assign your project ID here

  return(
    <div>
      <VisitorAPIComponents projectId={visitorApiPrjectId} handleCountryChange={(countryObj) => setCountry(countryObj)} handleStateChange={(stateObj) => setState(stateObj)}>
        <CountryField label="Country/Territory"></CountryField>
        <StateField label="State/Province"></StateField>
      </VisitorAPIComponents>
      Your country is {country !== null && country.label} and your state is {state !== null && state.label}.
    </div>
  );
}
```

## Enable the geolocation detection

The package uses a server-side API from [VisitorAPI](https://www.visitorapi.com). There is a prop named `projectId` which you need to assign with a valid project ID from VisitorAPI to enable the geolocation detection.

To get a valid project ID, create a free plan or a paid plan depending on your volume of monthly API calls. Once you created a plan, you can see your VisitorAPI project ID in the project dashboard and your API usage. Simply copy and place your VisitorAPI project ID and reload your React application, the fields will be set with your current country and state when they are loaded.

Because VisitorAPI is designed to be used in the frontend so it doesn’t need an API key to authorise the API calls, as any key would be exposed to the Internet and that defeats the purpose of having a key anyway. The API uses the origin of the API requests to authorise the calls and you must put your domain (e.g. yourname.com) into the authorised domain list in the project settings UI of your VisitorAPI project, or it will deny your API calls.

## Resources

The component GitHub repo: https://github.com/visitorapi/react-country-state-fields

The example GitHub repo that demonstrates how the components are used: https://github.com/visitorapi/react-country-state-fields-example