Get user location by IP address with JavaScript

OpenJavaScript 0
Reading Time: 4 minutes 🕑

Last updated: September 13, 2022.

Being able to locate a user by country allows you to personalize user experience.

Especially in a world of uneven privacy laws where some contents can be shown in some areas and not in others, it is increasingly essential to be able to at least detect the country of a user.

By checking the location a user by IP, you can check location in the background without bothering the user (though you need to make sure you solution is privacy-compliant).

Using JavaScript, you have two options for resolving the location of a user by their IP address: by resolving the IP and location via third-party service or querying a database hosted on your own server using Node.js.

Table of contents

Frontend solution

It is not possible to obtain the IP address of a user client-side (i.e. running JavaScript in the browser).

However, you can still make a HTTP request to a third-party service that will process the IP and link it to a location on your behalf.

One such service is Geolocation API. All you need to do is make a GET request to their server.

For example, enter the following endpoint into your browser and you will be served a JSON file containing lots of information about your current location:

http://ip-api.com/json/?fields=61439

In practice, you’ll want to make a formal HTTP to the server in JavaScript.

Below is a request made using the native Fetch API (no library needed):

fetch('http://ip-api.com/json/?fields=61439')
  .then(res => res.json())
  .then(res => console.log(res));

A successful server response will look like the output below in the browser console:

{
  "query": "24.48.0.1",
  "status": "success",
  "country": "Canada",
  "countryCode": "CA",
  "region": "QC",
  "regionName": "Quebec",
  "city": "Montreal",
  "zip": "H1K",
  "lat": 45.6085,
  "lon": -73.5493,
  "timezone": "America/Toronto",
  "isp": "Le Groupe Videotron Ltee",
  "org": "Videotron Ltee",
  "as": "AS5769 Videotron Telecom Ltee"
}

This is just one example using Geolocation API. Other services are available.

Privacy concerns

Though this is a workable solution, it does raise an important privacy issue.

That is, to resolve the location of a user, data is sent to an external server for processing. A server over which you have no control!

So, in production environments where the location of all users must be check (including those coming from countries with strict privacy laws) it is more privacy-optimal to handle the data yourself.

By handling the data yourself, you can ensure that your data-processing practices are consistent with relevant data privacy regulations.

Backend solution using Node.js

By creating a Node.js app – an environment for running JavaScript server-side – you can detect the IP address of a user and use this information to determine user location.

To do so, you look up the IP address of a user in a database that you host on your own server.

In the following example, we will use a database that has been downloaded from MaxMind.

Downloading the database and query API

First, you need to register with MaxMind. Once you have, you’ll have access to download options for their GeoLite2 database (free version). Download the binary version of this database (file extension .mmdb) and place this in a project folder.

Now, from the command line, navigate to this new project folder and create a new Node project by calling npm init while in the folder and accepting all default settings.

Now, it is time to install the MaxMind API that will allow you to query the database using relatively simply sytnax.

To install, run the following in your terminal:

npm install @maxmind/geoip2-node

Making database queries

You are now able to query the database with a JavaScript file in your project folder by importing the installed MaxMind API at the top of your script and calling reader.country(), passing in an IP address.

Here is the recommended syntax for interacting with the API

const Reader = require('@maxmind/geoip2-node').Reader;

Reader.open('./GeoLite2-Country.mmdb').then(reader => {
  const response = reader.country('123.123.123.123');

  console.log(response.country.isoCode);
});

Notice the IP above is hard-coded. That’s not what you want in practice!

The first modification we’ll make is wrap this database query in a new server created using the native http module.

This means the database query now runs when a request (page visit) is registered at localhost:3000. The IP address of a user making this request can be determined.

But first, here’s the code to get the server up and running on port 3000.

const http = require('http');
const Reader = require('@maxmind/geoip2-node').Reader;

http.createServer(function (req, res) {

  Reader.open('./GeoLite2-Country.mmdb').then(reader => {
    const response = reader.country('123.123.123.123');

    console.log(response.country.isoCode);
  });

  res.end();
}).listen(3000);

The final piece of the puzzle is to determine the IP address of where the request is coming from.

For this, you simply need to call req.socket.remoteaddress on the request object.

Simply feed the returned value into the reader.country() method and, if the IP is found in the database, the country of origin will be returned.

const http = require('http');
const Reader = require('@maxmind/geoip2-node').Reader;

http.createServer(function (req, res) {

  const userIp = req.socket.remoteaddress;

  Reader.open('./GeoLite2-Country.mmdb').then(reader => {
    const response = reader.country(userIp);

    console.log(response.country.isoCode);
  });

  res.end();
}).listen(3000);
Using Node.js

If you have installed and imported the (insanely popular) Express package into your project, you can get the IP of the requester by simply calling req.ip.

Testing locally vs live

Note that if you are testing this locally, the IP address will not be found in the database because the request os locla.

It will, however, work when live because then the request is coming from a public IP address. And these are listed in the database.

For testing purposes, it is therefore recommended to use a hardcoded value to prevent an error and use the dynamically determined IP value in production.

Summary

Using JavaScript, you can get the location of a user by IP address by using a third-party service that will resolve the IP and location of a user for you.

A more privacy-friendly way is to process the data on your own server, using a database to look up the location of a user’s IP. This second method allows you to fully control the processing of data without it leaving your server.