Geolocate an IP address using Web Services with the client-side JavaScript

Our GeoIP2 JavaScript client allows you to use GeoIP2 web services client-side without doing any server-side integration on your end. While it is convenient, there are some caveats with its usage. Some browser settings and add-ons (such as ad blockers) may prevent the GeoIP2 JavaScript API from successfully calling the web services. Additionally, there may be unexpected usage spikes which you may want to monitor, due to moments of high traffic to your website(s).

We highly recommend using a server-side integration, as it is more secure and more robust than a client-side integration.

Implementation

Implementing the GeoIP2 JavaScript client involves registering your domain(s), adding a JavaScript snippet to your web page, calling the desired API method/service, and providing callbacks for all scenarios.

1. Register your domain(s)

All domains using the service must be registered. New users may request a free trial or purchase web service credit in order to receive an account to register domains. Existing account holders are able to register domains directly.

2. Add a JavaScript snippet to your page

In order to use this service, the following JavaScript must be included in your page.

Do not download this JavaScript file and serve it from your server(s)!

The JavaScript file must be served from MaxMind servers, otherwise GeoIP2 requests will fail.

1<script src="https://geoip-js.com/js/apis/geoip2/v2.1/geoip2.js" type="text/javascript"></script>

3. Call an API method and provide callbacks

The JavaScript client provides 3 public methods:

OptionDescription
geoip2.country(onSuccess, onError, options)Calls the “GeoIP2 Country” endpoint using the routable IP address associated with the machine on which it is running.
geoip2.city(onSuccess, onError, options)Calls the “GeoIP2 City Plus” endpoint using the routable IP address associated with the machine on which it is running.
geoip2.insights(onSuccess, onError, options)Calls the “GeoIP2 Insights” endpoint using the routable IP address associated with the machine on which it is running.

All of the functions take the same 3 arguments:

  • If successful, this function calls the onSuccess callback. The first parameter passed to the callback contains an object matching the output of one of MaxMind’s GeoIP2 web service API responses.

    In addition to the attributes listed in the web services API docs, the object also has a most_specific_subdivision property that provides access to the most specific subdivision object available. On browsers other than Internet Explorer 8, this is implemented as a non-enumerable property using defineProperty.

  • If there is an error, the function calls the onError callback with the error object as a parameter.

  • The optional options parameter is an object containing flags for the service. This parameter is reserved for future use. There are no options at this time.

Example: Display the user’s city name in a page

In this example, we are displaying the user’s city name in a page. We have 2 files: page.html and demo.js.

 1<!-- page.html -->
 2<!doctype html>
 3<html>
 4  <head>
 5    <title>Which city am I in?</title>
 6    <script src="https://geoip-js.com/js/apis/geoip2/v2.1/geoip2.js"></script>
 7    <!-- make sure this is after the geoip2.js file -->
 8    <script src="/demo.js"></script>
 9  </head>
10
11  <body>
12    <p>
13       Where am I?
14    </p>
15
16    <p>
17      You are in <span id="city"></span>.
18    </p>
19  </body>
20</html>
 1// demo.js
 2var fillInPage = (function() {
 3  var updateCityText = function(geoipResponse) {
 4
 5    /*
 6     * It's possible that we won't have any names for this city.
 7     * For language codes with a special character such as pt-BR,
 8     * replace names.en with names['pt-BR'].
 9    */
10    var cityName = geoipResponse.city.names.en || 'your city';
11
12    document.getElementById('city').innerHTML = cityName
13  };
14
15  var onSuccess = function(geoipResponse) {
16    updateCityText(geoipResponse);
17  };
18
19  // If we get an error, we will display an error message
20  var onError = function(error) {
21    document.getElementById('city').innerHTML = 'an error!  Please try again..'
22  };
23
24  return function() {
25    if (typeof geoip2 !== 'undefined') {
26      geoip2.city(onSuccess, onError);
27    } else {
28      document.getElementById('city').innerHTML = 'a browser that blocks GeoIP2 requests'
29    }
30  };
31}());
32
33fillInPage();

Successful responses

A successful response consists of a single JavaScript object. That object contains a set of key/value pairs, where the keys are things like country and traits, and the values are objects or arrays of objects.

While our REST API is documented as omitting missing keys, we add blank arrays and objects in the JavaScript API. This makes it much simpler to work with the response, as you will not need to check whether the data structure exists before using it.

Wherever a missing property’s value could be an object or array, we will add an empty object or array as needed. For example, if you call the city() method and the response from the MaxMind server has no city key at all, it will end up being filled in as:

1{
2  "city": {
3    "names": {}
4  },
5  "country": {...},
6  "continent": {...},
7  ...
8}

If the response contains no subdivisions key, you will get this:

1{
2  "city": {...},
3  "country": {...},
4  "continent": {...},
5  "subdivisions": [ { "names": {} } ],
6  ...
7}

Errors

All errors are passed in a JavaScript object as the first parameter to the onError function. This object contains two keys, code and error. code is a machine-readable error code that will not change. error is a human-readable description of the error.

CodeHTTP StatusDescription
IP_ADDRESS_INVALID400 Bad RequestYou have not supplied a valid IPv4 or IPv6 address.
IP_ADDRESS_REQUIRED400 Bad RequestYou have not supplied an IP address, which is a required field.
IP_ADDRESS_RESERVED400 Bad RequestYou have supplied an IP address which belongs to a reserved or private range.
IP_ADDRESS_NOT_FOUND404 Not FoundThe supplied IP address is not in the database.
DOMAIN_REGISTRATION_REQUIRED401 UnauthorizedThe domain of your site is not registered.
QUERY_FORBIDDEN401 UnauthorizedYou tried to access a service or feature that is not covered by your service plan.
OUT_OF_QUERIES402 Payment RequiredThe license key you have provided is out of queries. Please purchase more queries to use this service.
PERMISSION_REQUIRED403 ForbiddenYou do not have permission to use the service. Please contact our support team for more information.
HTTP_TIMEOUT(none)The request to the GeoIP2 web service timed out.
HTTP_ERROR(none)There was an error making the request to the GeoIP2 web service.

Versioning

This document covers version 2.1 of the GeoIP2 JavaScript API. Whenever MaxMind releases a new version of the JavaScript API, we will use a new path, so the old JavaScript files will always be accessible. For example, if we released version 42.6 of the JavaScript API, its path would be /js/apis/geoip2/**v42.6**/geoip2.js.

However, support will only be provided for the newest version of the JavaScript API at any given time.

Please note that the JavaScript API and the web service REST API are versioned separately. We will bump the JavaScript API version when we add new features or need to break backwards compatibility with previous versions of the JavaScript API.

Version 2.1 of the JavaScript API uses version 2.1 of the GeoIP2 web services REST API.

Browser support

MaxMind is committed to support all browser versions that are currently supported by their respective creators. When the creator offers multiple support levels, we only support the browser through its initial support phase. For example, Microsoft has two support phases, Mainstream and Extended. We are committed to supporting browsers through the end of the Mainstream support phase. We reserve the right to end support at any time for any browser no longer supported by its creator. In order to ensure your data is as safe and secure as possible, we recommend using the encrypted HTTP (HTTPS) protocol.

Here is the list of browsers supported:

BrowserVersion(s)
ChromeLast two stable releases per Chrome Release Stable Channels
Firefox60+
Internet Explorer11
Edge17+
Safari (desktop and mobile)10+
OperaCurrent release
Android native browser5+
iOS native browser10+

Security

We require TLS 1.2 or greater for HTTPS requests to our servers to keep your data secure.