Issues with WordPress geo-blocking implementation in functions.php

I’m working on a geo-blocking feature for my WordPress site to prevent users from a specific country from accessing certain pages. The aim is for these visitors to be redirected to the homepage automatically.

Here’s the code I’ve been using in functions.php:

function redirect_users_from_country() {
    if (!isset($_SERVER["REMOTE_ADDR"])) {
        error_log("Unable to find IP address.");
        return;
    }

    $client_ip = $_SERVER["HTTP_X_FORWARDED_FOR"] ?? $_SERVER["REMOTE_ADDR"];
    error_log("Geo-blocking check for IP: " . $client_ip);

    $geo_response = wp_remote_get("http://ipinfo.io/{$client_ip}/json");

    if (is_wp_error($geo_response)) {
        error_log("Geo-block API failed: " . $geo_response->get_error_message());
        return;
    }

    $geo_info = json_decode(wp_remote_retrieve_body($geo_response), true);

    if (empty($geo_info["country"])) {
        error_log("No country information received.");
        return;
    }

    error_log("User's IP {$client_ip} is located in {$geo_info["country"]}");

    if ($geo_info["country"] !== "BE") {
        error_log("Visitor is not from Belgium.");
        return;
    }

    $current_request_path = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
    $restricted_page_path = "my-geo-blocked-url";

    error_log("Current URL: {$current_request_path}");
    
    if ($current_request_path !== $restricted_page_path) {
        error_log("Visitor is not on the blocked page.");
        return;
    }

    error_log("Redirecting user from {$current_request_path}");
    wp_safe_redirect(home_url());
    exit;
}
add_action("template_redirect", "redirect_users_from_country");

According to my logs, the IP is correctly detected, but I’m receiving an empty country response. The redirect does not work as intended. What could be the issue?

Empty country response means your API requests are failing silently. I’ve hit this exact issue with geolocation APIs - they’ll return HTTP 200 even when the request bombs, so wp_remote_get won’t catch the error. Log the raw response body before you decode it to see if you’re actually getting valid JSON back. Half the time the API spits out plain text or HTML error messages instead of JSON when your request format is wrong. Also, some hosts block outbound HTTP requests on port 80 for security. Try switching to HTTPS instead of HTTP when you call ipinfo.io. Fixed the same problem for me on shared hosting - HTTP was blocked but HTTPS worked fine.

Had the same geo-blocking headaches a few months ago. Your IP parsing is probably the culprit here. When you grab HTTP_X_FORWARDED_FOR, it often returns multiple IPs with commas - that’ll break your API call every time. Just split the string and grab the first IP.

Also, ipinfo.io can be spotty with certain IP ranges, especially CDNs and proxies. I’d throw in a backup like ip-api.com and validate the IP before hitting any API. And definitely cache those geo-lookups temporarily - you don’t want to slam into rate limits while testing.

hey! ipinfo.io might be rate limiting you or requiring an api key now. try adding a user agent header to your wp_remote_get call, or switch to geoplugin.net - it’s much more reliable for free usage.