Say you need to know what country someone visiting your website is from, because you have an internationalized site and display different things based on that country. You could ask the user. You might want to have that functionality anyway to make sure your visitors have control, but surely they will appreciate it just being correct out of the gate, to the best of your ability.
There are no native web technologies that have this information. JavaScript has geolocation, but users would have to approve that, and even then you’d have to use some library to convert the coordinates into a more usable country. Even back-end languages, which have access to the IP address in a way that JavaScript doesn’t, don’t just automatically know the country of origin.
CANADA. I JUST WANNA KNOW IF THEY ARE FROM CANADA OR NOT.
You have to ask some kind of service that knows this. The IP Geolocation API is that service, and it’s free.
You perform a GET against the API. You can do it right in the browser if you want to test it:
https://api.ipgeolocationapi.com/geolocate/184.149.48.32
But you don’t just get the country. You get a whole pile of information you might need to use. I happen to be sitting in Canada and this is what I get for my IP:
{
"continent":"North America",
"address_format":"{{recipient}}\n{{street}}\n{{city}} {{region_short}} {{postalcode}}\n{{country}}",
"alpha2":"CA",
"alpha3":"CAN",
"country_code":"1",
"international_prefix":"011",
"ioc":"CAN",
"gec":"CA",
"name":"Canada",
"national_destination_code_lengths":[
3
],
"national_number_lengths":[
10
],
"national_prefix":"1",
"number":"124",
"region":"Americas",
"subregion":"Northern America",
"world_region":"AMER",
"un_locode":"CA",
"nationality":"Canadian",
"postal_code":true,
"unofficial_names":[
"Canada",
"Kanada",
"Canadá",
"カナダ"
],
"languages_official":[
"en",
"fr"
],
"languages_spoken":[
"en",
"fr"
],
"geo":{
"latitude":56.130366,
"latitude_dec":"62.832908630371094",
"longitude":-106.346771,
"longitude_dec":"-95.91332244873047",
"max_latitude":83.6381,
"max_longitude":-50.9766,
"min_latitude":41.6765559,
"min_longitude":-141.00187,
"bounds":{
"northeast":{
"lat":83.6381,
"lng":-50.9766
},
"southwest":{
"lat":41.6765559,
"lng":-141.00187
}
}
},
"currency_code":"CAD",
"start_of_week":"sunday"
}
With that information, I could easily decide to redirect to the Canadian version of my website, if I have one, or show prices in CAD, or offer a French translation, or whatever else I can think of.
Say you were in PHP. You could get the IP like…
function getUserIpAddr() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
The cURL to get the information:
$url = "https://api.ipgeolocationapi.com/geolocate/184.149.48.32";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
It comes back as JSON, so:
$json = json_decode($result);
And then $json->{'name'};
will be “Canada” if I’m in Canada.
So I can do like:
if ($json->{'name'} == "Canada") {
// serve index-ca.php
} else {
// server index.php
}
I’ve always used the ip2location in the backend for this. There’s a free version that gives all of this information, and a paid version which can even pinpoint the IP to a city. It doesn’t give language information, but lookup by country isn’t the way to do that anyway (that should be done by looking at
navigator.languages
).This can easily be passed back in the return body of the first request to any JavaScript that needs it (API calls from the browser are expensive).
The main advantage is removing a dependency on a third party. If that service is down or unreachable, it affects your site.
Having recently returned to the US after almost ten years of living (rather happily) in Taiwan, I cannot over emphasize my rage at those web sites (and others) who were wont to decide for me that I necessarily wanted everything to be in Chinese. While I have nothing against Chinese, I have a hearing defect that precludes me from understanding spoke Chinese and I eventually gave up trying to learn the language.
May I politely suggest that developers let the end-user decide which language they want, instead of deciding for them.