GeoIP on WordPress

Detecting a visitor's location can provide a semi-customized experience that can work out well. However, it can also lock visitors into an assumption that is incorrect, and that may create a worse experience. For example, changing default languages based on location is not a good idea (it is better to use cookies and reasonable defaults, but auto-switching is a bad experience (I'm looking at you Paypal, Google, and Apple).

Locations Determine Laws and Defaults

The laws of a country apply to those in that country, but also should be seen as expectations for those coming from that country. Cookie laws and privacy policies are a clear example. If someone is physically located (or has a VPN endpoint) in a given country, assume they should be treated as per the laws of the land (at a very basic level, though this can be improved for better experiences).

A second example is currency preference and denomination. These are most appropriate when reflecting the currency of the country of origin.

A third example is when showing outbound links is to make those as useful as possible. For destinations such as Amazon and Kobo, the links are specific to the presumed country store location (or one nearby). There are third party services (such as A-FWD) that can take a single link and then do a rewrite based on the visitor IP, but that requires that the service will continue to work (and essentially it is getting inbound links and can do whatever they want with the redirected visitor). The additional limitation is that while there are several for Amazon links, other multi-destination sites aren't (such as Kobo), and so several solutions are needed, whereas one would be the best.

And of course language settings are something that can be set based on location awareness (but this it seems can go wrong in the worst way, namely providing a language that the visitor cannot read (and cannot understand enough to set the language properly).

First, Do No Harm

The main thing is to not make the experience worse. This means everything that a site sets as a default (based on detection) should all a user override mechanism that is simple and obvious. This should be thought out well in advance, and the changing mechanism developed first.

One approach, if some kind of content will be displayed based on location, is to allow for others to be displayed (say, all other options), while hiding those behind a toggle of some kind. This helps keep the UI clean, while allowing for a fallback if visitor location does not accurately capture visitor needs. For WordPress, there is a useful plugin WP-ShowHide that works well. It provides shortcodes, and supports multiple show/hides on a given page. Just change the type="" text to a unique value.

GeoIP and WordPress Plugin

GeoIP is a classic database of IP addresses and the function to do a quick lookup and determine location based in IP address. There are a variety of functions and features, but the main point is that the GeoLite2 database is free.

GeoIP can be installed as an Apache (or Nginx) plugin, and then used from a .htaccess file for rewriting. However, it is easily accessible as a simple, open source WordPress Plugin wp-geoip-detect (with database auto-updates), and shortcode/php api. This provides greater functionality, at the level of pages and content elements.

PHP Code for GeoIP

One approach is to just manhandle everything in an embedded PHP script, using a plugin such as wp-exec-php.

`country->isoCode == 'AU') echo "G'day, mate!"; else echo "Hello, sir!";


country->isoCode == 'AU')
    echo "G'day, mate!";
    echo "Hello, sir!";

## Use of GeoIP with CSS

CSS is a good approach for hiding or displaying marked up divs or spans, since it is probably the fastest (though it may bloat up the html file size).

.geoip { display: none !important; } .geoip-country-HK .geoip-show-HK { display: block !important; }

Shipping to Hong Kong is especially cheap!

However, as noted in the [plugin FAQ]( > You need to enable the option Add a country-specific CSS class to the `` Tag to make this work. This is a huge drawback if one has caching since that means every page is not cached, as it is a global setting. Instead, add the `.geoip-country-XY` programmatically to the DIV with:

Shipping to Hong Kong is especially cheap!

Shipping to Hong Kong is especially cheap!
Unfortunately the shortcode does not work inside a div. Another option is to try writing it out in PHP as such: `<?php`

$userInfo = geoip_detect2_get_info_from_current_ip(); echo '

country->isoCode ; echo ' geoip-show-HK">Shipping to Hong Kong is especially cheap!
'; // repeat the last three lines for any permutations by country ~~~ ?>

<?php $userInfo = geoip_detect2_get_info_from_current_ip(); echo '

country->isoCode ; echo ' geoip-show-HK">Shipping to Hong Kong is especially cheap!

'; // repeat the last three lines for any permutations by country ?>

Summary and Further Research

  • Likely the initial PHP Code for GeoIP above with if/elseif/else is the simplest to read, without the CSS.
  • It is probably better to get the GeoIP working as an Apache module, and then use PHP to read the request variable country.
  • Use of WP Show/Hide plugin is a nice way to hide/degrade other options in case geolocation is not the same as the user preference.
  • Ultimately, one can in many cases, if the user base is highly skewed to a particular country, show that country's local link, and use show/hide to allow everyone to see the other options.