Skip to content
Benjamin Pick edited this page Dec 12, 2020 · 27 revisions

You are using a site cache? This is what AJAX mode is made for.

If the cached HTML is geo-independent, yet it should be customized depending on the geo-data, then now you can use this AJAX call to figure out the user's location. You can then use this information to show/hide content, inject the country name into a field, redirect to a different page, etc.

JSON Endpoint

GET https://example.com/wp-admin/admin-ajax.php?action=geoip_detect2_get_info_from_current_ip

The function geoip_detect2_get_info_from_current_ip() can be called via JS and returns the JSON data. This only works if the option "Enable JS API" is checked.

HTTP Response Codes

Code Meaning
200 OK (but properties might be empty)
500 Lookup Error (e.g. file is corrupted)
412 AJAX Setup Error

JSON Response object

The result from the datasource. See Record Properties for all available properties. No property name is guaranteed to exist:

var city = record.city && record.city.names && record.city.names.en;
var ip = record.traits && record.traits.ip_address;
var error = record.extra && record.extra.error;

Caveats:

  • It is not possible to prevent securely that no other website is using this JSON Endpoint. That's why it is discouraged to use it for paid APIs like Maxmind Precision.
  • In order to improve this situation a little bit, the AJAX call is testing the HTTP referer. If the referer domain is not the same domain as the wordpress site_url(), then the AJAX call will be rejected. (However, Referers may be forged easily.) If you are using other domains as source, add them to the wordpress filter geoip_detect2_ajax_allowed_domains.
  • Also, only geoip_detect2_get_info_from_current_ip can be called in this way, you cannot pass an IP as a URL parameter. (But still, client IPs can be forged - it's hard to do but possible.)
  • If you need to change the options such as skipCache, set them in the wordpress filter geoip_detect2_ajax_options.

Frontend JS (helper functions)

This JS provides an JS API to access the data returned by the JSON Endpoint. Enable the option Add JS to make the access to the AJAX endpoint easier. or enqueue the JS file manually

// Example to show JS usage
// This example assmues that jQuery is available on your frontend - jQuery is not required for the JS code of the plugin

jQuery(document).ready(function($) {
  geoip_detect.get_info().then(function(record) {
    if (record.error()) {
      console.error('WARNING Geodata Error:' + record.error() );
      $('.geo-error').text(record.error());
    }

    // Debug: Show raw data of record. (Warning: No property in this object is guaranteed to exist.)
    // console.log('Record', record.data);

    // If no locales are given, use the website language
    $('.geo-continent').text(record.get('continent')); 

    // Second parameter is the default value if the property value is empty or non-existent. For example, the IP might be from a satellite connection.
    $('.geo-continent').text(record.get('continent', 'Weird: no country detected.'));
    
    // Return the German name of the country, if not available, use English
    $('.geo-country').text(record.get_with_locales('country', ['de']));
    
    // Return the German name of the country, if not available, show "default text"
    $('.geo-country-de').text(record.get('country.names.de', 'default text'));
    
    // Try French first, then German, then English. The pseudo-property "name" is also supported ('city' would result in the same return value).
    $('.geo-city').text(record.get_with_locales('city.name', ['fr', 'de', 'en'], 'No city detected.'));
    
    // The same property names can be used as in the shortcode syntax 
    $('.geo-city-id').text(record.get('city.geoname_id'));
    $('.geo-ip').text(record.get('traits.ip_address'));

  });

  // This will return the same JS promise as above, so that this will not result in a second AJAX request.
  geoip_detect.get_info().then(function(record) {
    $('.geo-country-2').text(record.get_with_locales('country', ['en']));
  }); 

});
Continent: <span class="geo-continent"></span><br>
Country (de): <span class="geo-country"></span><br>
Country (de): <span class="geo-country-de"></span><br>
City (fr,de,en): <span class="geo-city"></span><br>
City-Id: <span class="geo-city-id"></span><br>
IP: <span class="geo-ip"></span><br>
Error: <span class="geo-error"></span><br>

Country (en): <span class="geo-country-2"></span><br>

By default, the result is cached in a browser cookie so that subsequent visits by the same visit will not issue a new AJAX request. You can configure this behaviour in your theme's function.php like this:

add_filter('geoip_detect2_ajax_localize_script_data', function($data) {
    $data['cookie_name'] = ''; // Disable cookies completely
    // or $data['cookie_duration_in_days'] = 14 // How long the cookie is valid, default is 1 (day)
    return $data;
});

Enqueue the JS file manually

If you only need this JS on some sites, enqueue the JS file manually and uncheck the option Add JS to make the access to the AJAX endpoint easier..

You can add the shortcode [geoip_detect2_enqueue_javascript] (since 3.3.0) on the pages/posts where you have geo-dependent content.

Or, if you need a more general solution:

$whitelist = [
	'/' /* home */,
	'/some/query/',
	'/other/page/'
];

$server_request = $_SERVER['REQUEST_URI'];
// Comment this line if you also want to match GET parameters like /path/?page=34
$server_request = parse_url($server_request, PHP_URL_PATH);

if (in_array($server_request, $whitelist)) {
	geoip_detect2_enqueue_javascript();
}

Country-specific CSS class for the -Tag

If you have enabled the option Add a country-specific CSS class to the <body>-Tag., enabling AJAX mode and Frontend JS will add these CSS classes via AJAX as well.

Clone this wiki locally