Moved to: WoodyHayday.com
Woody Hayday

Fresh Ideas

Hi there! This is my old blog, I don't hang around here much.
You can now find me trying to mix things up here:
Visit WoodyHayday.com Subscribe To My Email List

IP to Location Alternative: Javascript – Using JS to find Browser Country / Location not from IP

Know your audience? Got google analytics aggregating their details? Great, good for you! But doe’s that add any value in the short term? Improve THEIR browsing experience? In the long run you should use analytics to achieve better sites (although many don’t) – but for now, right here you can still add some of the future frill. Take this situation: You want to show different content/additional content to each nationalities (maybe aim for a few – US, UK, AUS) – Did you know that adding a national flag that a user can associate with may increase sales up to 20%, or More? Go read Ca$hvertising. In any case if your sitting comfortably, take a look below for the how to!

Mars Landers on Map
Javascript – Using JS to find Browser Country / Location not from IP Photo by ToastyKen

Common solutions to identifying a users locale/localizing/localising a web client:

Using PHP / ASP.NET take the users IP and feed into an ip to location service (geo ip) to find a country from ip.
Pro’s: Server-side off the bat, can cache a database of IP’s (although would you?)
Con’s: Adds another 2 hops to at least initial page load, IP location service’s can cost or be faulty

Using the request headers (again server-side) to identify an “accepted language” and then guestimating their location (taking en-US…for example.)
Pro’s: Server-side to start with, no extra hops/calls required, this data is already available whether you use it or not, more useful for language (although limited)
Con’s: Unreliable – mostly because of a few of the BIG browsers default to en-US for all english users, often international users might learn to use a browser in English anyway – defeating the point

Another solution (work in progress:)

A step towards a proper solution, and in my case a solution for MY original problem, is to at least work out their TIMEZONE. What? I hear you say, why the timezone? Well if you know, for example using analytics data, that your user base is 40% US, 50% UK and 10% rest of the world you can at least make a START by dealing with the two major constituents of your audience. I can envisage A more complete solution though, by combining the use of request headers accepted language AND the following Javascript timezone detection:

Searching around a bit I found this which showed a lot of promise. This javascript works out the users Operating System time offset, and from that you can define which timezone they are in. Useful, if like me you know your users in a specific timezone are likely to be in one country, not particularly if they are possibly in multiple countries within a timezone.

A solution / exploration – location detection in javascript

The following Javascript gives you both indicators, using navigator.language/systemlanguage it detects the browser’s language, and then using an expanded upon version of the above script it will provide you with the possible countries from the users OS timezone offset. How useful this is to you is depending on the application, but check it out – build some fantastic solution off of it, then show me, because I probably won’t get round to it!

var langCode = navigator.language || navigator.systemLanguage;
var lang = langCode.toLowerCase(); lang = lang.substr(0,2);

var dateObject = new Date(); //this timezone offset calc taken from http://unmissabletokyo.com/country-detector.html
var timeOffset = - dateObject.getTimezoneOffset() / 60; 
var c = ""; //this will ultimately end up as a country/csv of possible countries
switch (timeOffset) { //I expanded upon this switch, adding all the possible countries
	case 0: 
	 c = 'Algeria, Ascension Island, Burkina Faso, Faeroe Islands, Ghana, Guinea Republic, Iceland, Ireland, Ivory Coast, Liberia, Mali, Morocco, Sao Tome & Principe, Senegal, Sierra Leone, St Helena, The Gambia, Togo, United Kingdom'; break;
	
	case 1: 
	 c = 'Albania, Andorra, Angola, Australia, Austria, Belgium, Benin, Bosnia, Cameroon, Central Africa Republic, Chad, Congo, Croatia, Czech Republic, Democratic Republic of Congo (Zaire), Denmark, Equatorial Guinea, France, Gabon, Germany, Gibraltar, Guam, Hungary, Italy, Liechtenstein, Luxembourg, Macedonia (Fyrom), Malta, Mariana Islands, Marshall Islands, Micronesia, Monaco, Netherlands, Niger, Nigeria, Norway, Papua New Guinea, Poland, Portugal, San Marino, Serbia, Slovak Republic, Slovenia, Spain, Sweden, Switzerland, Tunisia'; break;
	 
	case -1: 
	 c = 'Cape Verde Islands, Cook Islands, French Polynesia, Guinea Bissau, USA'; break;
	 
	case 11:	
	 c = 'New Caledonia, Solomon Islands, Vanuatu'; break;
	 
	case -11:
	 c = 'Niue Island, Samoa (American), Samoa (Western), USA'; break;
	 
	case 11.5:
	 c = 'Norfolk Island'; break;
	 
	case 12:	
	 c = 'Fiji Islands, Kiribati, Nauru, New Zealand, Tuvalu, Wallis & Futuna Islands'; break;
	 
	case 13:
	 c = 'Tonga'; break;
	 
	case 2:	
	 c = 'Botswana, Bulgaria, Burundi, Cyprus, Democratic Republic of Congo (Zaire), Egypt, Finland, Greece, Israel, Jordan, Lebanon, Lesotho, Libya, Lithuania, Malawi, Mozambique, Namibia, Palestine, Romania, Rwanda, South Africa, Sudan, Swaziland, Syria, Turkey, Zambia, Zimbabwe'; break;
	 
	case 3:
	 c = 'Bahrain, Belarus, Comoros Island, Djibouti, Eritrea, Estonia, Ethiopia, Iraq, Kenya, Kuwait, latvia, Madagascar, Mayotte Islands, Moldova, Qatar, Russia, Saudi Arabia, Somalia, Tanzania, Uganda, Ukraine, Yemen Arab Republic'; break;
	 
	case -3:
	 c = 'Argentina, Brazil, Cuba, Greenland, Guyana, Uruguay'; break;
	
	case 3.5:
	 c = 'Iran'; break;
	
	case -3.5:
	 c = 'Surinam'; break;
	
	case 4:
	 c = 'Armenia, Azerbaijan, Georgia, Mauritius, Oman, Reunion Island, Seychelles, United Arab Emirates'; break;
	
	case -4:
	 c = 'Anguilla, Antigua and Barbuda, Aruba, Barbados, Bermuda, Bolivia, Brazil, Canada, Chile, Dominica Islands, Dominican Republic, Falkland Islands, French Guiana , Grenada, Guadeloupe, Martinique, Montserrat, Netherlands Antilles, Paraguay, Puerto Rico, St Kitts & Nevia, St Lucia, Trinidad & Tobago, Venezuela'; break;
	
	case 5:
	 c = 'Diego Garcia, Maldives Republic, Pakistan, Turkmenistan'; break;
	
	case -5:
	 c = 'Bahamas, Brazil, Canada, Cayman Islands, Columbia, Ecuador, Haiti, Jamaica, Panama, Peru, Turks & Caicos Islands, USA'; break;
	
	case 5.5:
	 c = 'Bhutan,India,Nepal,Sri Lanka'; break;
	
	case 6:
	 c = 'Bangladesh, Kazakhstan, Kyrgyzstan, Tajikistan, Uzbekistan'; break;
	
	case -6:
	 c = 'Belize, Canada, Costa Rica, El Salvador, Guatemala, Honduras, Mexico, Nicaragua, USA'; break;
	
	case 6.5:
	 c = 'Myanmar (Burma)'; break;
	
	case 7:
	 c = 'Australia, Cambodia, Indonesia, Laos, Thailand, Vietnam'; break;
	
	case -7:
	 c = 'Canada, Mexico, USA'; break;
	
	case 8:
	 c = 'Australia, Brunei, China, Hong Kong, Indonesia, Macau, Malaysia, Mongolia, Philippines, Singapore, Taiwan'; break;
	
	case -8:
	 c = 'Canada, Mexico, USA'; break;
	
	case 9:
	 c = 'Australia, Indonesia, Japan, Korea, North, Korea, South, Palau'; break;
	
	case -9:
	 c = 'USA'; break;
}

//at this point Lang should be a 2 letter language code (e.g. en), timeOffset will be the users hour offset from GMT and c will be the csv of possible countries!
alert('Lang: ' + lang + "\r\n" + 'timeOffset: ' + timeOffset + "\r\n" + 'Possible Countries: ' + "\r\n" + c);

You can get the full source for this zipped here, included is a minified version wrapped in a function, isn’t that nice of me? Use it as you will, and if you create something epic, show me!

Countries/timezones: I built the timezone offset switch based on the wikipedia list of countries and their timezones, so its comprehensive.

This entry was posted in Javascript, Snippets, Web Development and tagged , , , , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.
Woody Hayday

Comments Archive

Hi there. This is my old blog and it's archived, so you can no longer post new comments on this post (IP to Location Alternative: Javascript – Using JS to find Browser Country / Location not from IP).

Read my new blog about writing software and stories at WoodyHayday.com

The New Blog
WoodyHayday.com
A Quote..
"I am not unfamiliar with horror, my memory is a faithful wife and my imagination, unlike myself, a diligent maid who sits quietly all day at her work and in the evening can speak so prettily for me that I just have to look at it even if.."
Søren Kierkegaard writing as Johannes de silentio
Old Random Projects
    © Woody Hayday 2008-2017