arraypress / wp-visitor-country
Resolve a visitor's country from CDN and server-level request headers (Cloudflare, AWS CloudFront, Fastly, BunnyCDN, mod_geoip). Zero dependencies, framework-agnostic, signature-gated to defeat trivial spoofing.
Requires
- php: >=8.3
Requires (Dev)
- phpcompatibility/phpcompatibility-wp: ^2.1
- phpunit/phpunit: ^12.0
- squizlabs/php_codesniffer: ^3.13.5
- wp-coding-standards/wpcs: ^3.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Read a visitor's country from the request headers your CDN already sets, instead of paying an API to look up their IP.
What it does
If your site sits behind Cloudflare, CloudFront, Fastly or BunnyCDN, the
country is already in the request — CF-IPCountry and friends. Most geo code
ignores that and calls a paid IP-lookup service for an answer it was handed
for free.
This reads those headers in priority order, checks the request actually came from the CDN before trusting them, and gives you an ISO-3166 alpha-2 code.
Features
- Get a country code from Cloudflare, CloudFront, Fastly, BunnyCDN or a server GeoIP module
- Refuse a spoofed header, by verifying the request came from the CDN that sets it
- Ask which source answered, when you need to know how much to trust it
- Register your own source for a GeoIP database or a lookup service
- Change the order sources are tried in, or replace the list outright
- Fall through cleanly to an empty string, so nothing has to be wrapped in a try
Installation
composer require arraypress/wp-visitor-country
Quick start
Charge the right tax, or show the right currency, without an API call:
use ArrayPress\VisitorCountry\Country; $country = Country::resolve(); // "GB", or "" when nothing answered if ( 'GB' === $country ) { // ... }
When it matters where the answer came from:
$result = Country::resolve_detailed(); $result->get_country(); // "GB" $result->get_source(); // which header answered $result->get_confidence(); // how much to trust it
A header no CDN in front of you sets is not trusted, so this is safe to act on — but it is a hint about the request, not a statement about the person, and a VPN will change it.
Requirements
- PHP 8.3 or later
- WordPress 7.1 or later
License
GPL-2.0-or-later