TL;DR: Use the IPGeolocation.io API to detect any visitor's country, currency code, currency symbol, and dial code from their IP address — no GPS prompt, no sign-in required. One API call returns everything. Free tier included.
What you'll build
By the end of this tutorial, you'll have a working JavaScript snippet that:
- Detects the visitor's country and country flag from their IP address
- Returns the local currency code, name, and symbol (e.g.
EUR,Euro,€) - Pre-fills a checkout/signup form with country, dial code, and currency — automatically, on page load
- Works in Vanilla JS, React, and Node.js
No browser permissions. No annoying "Allow location access" popups. Just a clean API call.
Why detect country and currency from IP?
When a user lands on your site, you already know roughly where they are — through their IP address. Most developers ignore this and make users manually select their country and currency, which:
- Creates unnecessary friction at checkout
- Increases form abandonment
- Makes your site feel generic to international visitors
According to IPGeolocation.io's own data, displaying prices in a visitor's local currency alone can increase conversion rates by up to 40%. Personalizing content by location can improve engagement by up to 70%.
IP-based geolocation is non-intrusive — you're not asking for GPS coordinates or requiring any user interaction. It works silently in the background and simply makes the experience feel tailored.
The API: IPGeolocation.io
IPGeolocation.io is a developer-focused IP intelligence API that returns geolocation, currency, timezone, ASN, and security data for any IPv4 or IPv6 address. It's one of the few providers that includes:
-
Currency data (
code,name,symbol) on the free plan - Country metadata (dial/calling code, TLD, spoken languages)
- Country flag URLs and country emoji — ready to drop into UI
- A JavaScript SDK available via npm and CDN
Free tier: 30,000 requests/month. No credit card required.
The endpoint we'll use: https://api.ipgeolocation.io/v3/ipgeo
Step 1: Get your free API key
- Go to ipgeolocation.io and sign up
- Copy your API key from the dashboard at
https://app.ipgeolocation.io/dashboard
That's it. No waitlist, no credit card.
Step 2: Make your first API call (Vanilla JS)
The simplest possible call — detect the current visitor's IP automatically:
// Detects the visitor's own IP automatically when no `ip` param is passed
async function getUserGeoData() {
const API_KEY = 'YOUR_API_KEY_HERE';
const response = await fetch(
`https://api.ipgeolocation.io/v3/ipgeo?apiKey=${API_KEY}&fields=location,currency,country_metadata`
);
const data = await response.json();
return data;
}
getUserGeoData().then(data => {
console.log('Country:', data.location.country_name);
console.log('Currency code:', data.currency.code); // e.g. "EUR"
console.log('Currency symbol:', data.currency.symbol); // e.g. "€"
console.log('Dial code:', data.country_metadata.calling_code); // e.g. "+49"
console.log('Flag URL:', data.location.country_flag);
});
Sample API response
Here's what a real response looks like for a visitor from Germany:
{
"ip": "85.212.44.10",
"location": {
"country_name": "Germany",
"country_code2": "DE",
"city": "Berlin",
"state_prov": "Berlin",
"country_flag": "https://ipgeolocation.io/static/flags/de_64.png",
"country_emoji": "🇩🇪",
"is_eu": true
},
"country_metadata": {
"calling_code": "+49",
"tld": ".de",
"languages": ["de"]
},
"currency": {
"code": "EUR",
"name": "Euro",
"symbol": "€"
}
}
Notice how much you get in a single request: country, city, EU membership status, dial code, language, and full currency details.
Step 3: Auto-fill a checkout form
Now let's wire this into a real form. This pattern works for signup, checkout, lead gen — anything where you want to reduce friction for international users.
HTML
<form id="checkout-form">
<label>Country
<div style="display: flex; align-items: center; gap: 8px;">
<img id="flag-img" src="" alt="" width="24" style="display:none;" />
<input type="text" id="country-input" placeholder="Detecting..." />
</div>
</label>
<label>Phone number
<div style="display: flex; gap: 6px;">
<input type="text" id="dial-code" style="width: 80px;" placeholder="+1" />
<input type="tel" id="phone" placeholder="Your phone number" style="flex:1;" />
</div>
</label>
<label>Preferred currency
<input type="text" id="currency-input" placeholder="USD" />
</label>
</form>
JavaScript — auto-fill on page load
async function prefillFormFromIP() {
const API_KEY = 'YOUR_API_KEY_HERE';
try {
const res = await fetch(
`https://api.ipgeolocation.io/v3/ipgeo?apiKey=${API_KEY}&fields=location,currency,country_metadata`
);
const data = await res.json();
// Fill country field
document.getElementById('country-input').value = data.location.country_name;
// Show country flag
const flagImg = document.getElementById('flag-img');
flagImg.src = data.location.country_flag;
flagImg.alt = data.location.country_emoji;
flagImg.style.display = 'inline';
// Fill dial code
document.getElementById('dial-code').value = data.country_metadata.calling_code;
// Fill currency
const currencyDisplay = `${data.currency.code} (${data.currency.symbol})`;
document.getElementById('currency-input').value = currencyDisplay;
} catch (err) {
console.error('Geolocation lookup failed:', err);
// Gracefully fall back — leave fields blank for manual entry
}
}
document.addEventListener('DOMContentLoaded', prefillFormFromIP);
UX tip: Always let the user override the pre-filled values. The goal is to reduce friction, not lock them in.
Step 4: Use the JavaScript SDK (optional but cleaner)
If you're working in a Node.js or bundled project, IPGeolocation.io has an official npm SDK that removes the need to hand-roll fetch calls.
Install
npm install ip-geolocation-api-javascript-sdk
Usage
import { IpGeolocationClient } from "ip-geolocation-api-javascript-sdk";
async function main() {
const client = new IpGeolocationClient({
apiKey: "YOUR_API_KEY",
});
try {
const response = await client.lookupIpGeolocation({
ip: "8.8.8.8",
});
console.log("Country:", response.data.location?.countryName); // "United States"
console.log("City:", response.data.location?.city);
console.log("Currency", response.data.currency?.code); // "USD"
} finally {
await client.close();
}
}
main().catch((error) => {
console.error(error);
});
The SDK handles authentication, error retries, and response parsing for you.
Step 5: Use it in React
Here's a clean React hook you can drop into any component:
import { useState, useEffect } from 'react';
function useIPGeo(apiKey) {
const [geoData, setGeoData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchGeo = async () => {
try {
const res = await fetch(
`https://api.ipgeolocation.io/v3/ipgeo?apiKey=${apiKey}&fields=location,currency,country_metadata`
);
const data = await res.json();
setGeoData(data);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchGeo();
}, [apiKey]);
return { geoData, loading, error };
}
// Usage in a component
export default function CurrencyBanner({ apiKey }) {
const { geoData, loading } = useIPGeo(apiKey);
if (loading) return <p>Detecting your location...</p>;
if (!geoData) return null;
const { currency, location, country_metadata } = geoData;
return (
<div className="geo-banner">
<img
src={location.country_flag}
alt={location.country_name}
width={20}
/>
<span>
Showing prices in <strong>{currency.name}</strong> ({currency.symbol})
for {location.country_name}
</span>
</div>
);
}
What fields does the API return?
Here's a quick reference for the fields most useful in localization and checkout flows:
| Field path | Example value | Use case |
|---|---|---|
location.country_name |
"Germany" |
Display name, form pre-fill |
location.country_code2 |
"DE" |
Passing to payment providers |
location.country_flag |
URL to PNG | Flag icon in UI |
location.country_emoji |
"🇩🇪" |
Inline emoji flag |
location.is_eu |
true |
Trigger GDPR consent banner |
currency.code |
"EUR" |
ISO 4217 currency for Stripe/payment APIs |
currency.name |
"Euro" |
Display label |
currency.symbol |
"€" |
Price display |
country_metadata.calling_code |
"+49" |
Phone number dial code |
country_metadata.languages |
["de"] |
Auto-select UI language |
Handling edge cases
What if the user is on a VPN?
If a user is tunneling through a VPN, the API will return the VPN server's country, not the user's real country. For checkout forms, this is usually fine — the user chose to appear in that country. If it matters for your use case (e.g., tax calculation), you can enable IPGeolocation.io's Security module alongside this call to detect VPN/proxy usage and prompt the user to confirm their location.
What about server-side rendering (Next.js)?
On the server, you have access to the real IP via request headers (x-forwarded-for or req.socket.remoteAddress). Pass that IP explicitly to the API:
// pages/api/geo.js (Next.js API route)
export default async function handler(req, res) {
const ip =
req.headers['x-forwarded-for']?.split(',')[0].trim() ||
req.socket.remoteAddress;
const API_KEY = process.env.IPGEO_API_KEY;
const response = await fetch(
`https://api.ipgeolocation.io/v3/ipgeo?apiKey=${API_KEY}&ip=${ip}&fields=location,currency,country_metadata`
);
const data = await response.json();
res.status(200).json(data);
}
Security note: Keep your API key in environment variables (
process.env.IPGEO_API_KEY). Never expose it in client-side JavaScript if you're on a paid plan.
Free tier limits and when to upgrade
| Plan | Requests/month | Currency data | Security data |
|---|---|---|---|
| Free | 30,000 | ✅ | ❌ |
| Paid | 150,000+ | ✅ | ❌ |
For most personal projects and small SaaS apps, the free tier is more than enough. Once you need VPN/proxy detection, threat scoring, or higher volume, upgrade to the Paid plan.
Frequently asked questions
Does IP geolocation work for IPv6?
Yes. IPGeolocation.io supports both IPv4 and IPv6 lookups natively. The API endpoint and response format are identical.
How accurate is IP-based country detection?
Country-level accuracy is typically above 99% for most IP ranges. City-level accuracy varies more. For currency and country pre-filling, country-level is all you need.
Can I use this on the frontend without an API key?
Yes — IPGeolocation.io supports keyless authentication via request origin (CORS allowlisting). You add your domain to the dashboard and the API authenticates requests from that domain automatically. This is ideal for frontend-only projects.
Does using IP geolocation require GDPR consent?
Detecting a country from an IP address for UX purposes (form pre-fill, currency display) is generally considered legitimate interest under GDPR — it doesn't involve storing or tracking personal data. Always consult your legal team for your specific use case.
What happens if the API is down or slow?
Always wrap the API call in a try/catch and provide a graceful fallback (leave fields empty, default to USD, etc.). IPGeolocation.io runs on Cloudflare's global network with a 99.99% uptime SLA on paid plans.
Summary
Here's what we covered:
- Why detecting country and currency from IP improves conversion and UX
- How to use the IPGeolocation.io
/v3/ipgeoendpoint to retrieve country, currency, flag, and dial code in one call - A Vanilla JS snippet to auto-fill a checkout form on page load
- The npm SDK for Node.js and bundled projects
- A React hook (
useIPGeo) ready to drop into any component - A Next.js API route pattern for server-side IP resolution
- Edge cases: VPN detection, SSR, GDPR, and API key security
The full API response gives you everything you need for a localized, frictionless experience — with zero popups, zero GPS requests, and zero user interaction required.
What's next?
-
Localize your full UI: Use
location.is_euto trigger GDPR banners,country_metadata.languagesto switch UI language automatically - Go offline: For high-traffic apps, IPGeolocation.io offers downloadable IP Geolocation Databases (MMDB, CSV, JSON) for sub-millisecond local lookups
Top comments (0)