Geo based redirects in WordPress let one short link serve different destinations per country: US visitors to your American storefront, UK visitors to the British one, everyone else to the default. This snippet implements country detection on top of GT Link Manager’s gtlm_redirect_url filter, with the lookup strategies ranked by reliability.
Requirements
- GT Link Manager 1.5+ installed and active
- CloudFlare (free tier is sufficient) for automatic country detection via the
CF-IPCountryheader, OR a hosting provider that sets geo headers
Installation
- Add the snippet below to your theme’s
functions.phpor a site-specific plugin - No constants to configure — geo mappings are stored per-link in the Notes field
- Ensure CloudFlare is active on your domain, or that your host provides geo headers
How to Use
Edit any link in GT Link Manager and add country-specific URLs in the Notes field using this format:
geo:US = https://example.com/us-store
geo:GB = https://example.com/uk-store
geo:DE = https://example.com/de-store
geo:FR = https://example.com/fr-storeUse ISO 3166-1 alpha-2 country codes (two uppercase letters). Visitors from a matching country get the localized URL. Everyone else gets the default destination.
The Code
<?php
/**
* GT Link Manager - Geo-Based Redirects
*
* Redirect users to different URLs based on their country.
* Best used with CloudFlare (free tier provides the CF-IPCountry header).
*
* How it works:
* - Store country-specific URLs in the link's "notes" field:
* geo:US = https://example.com/us-store
* geo:GB = https://example.com/uk-store
* geo:DE = https://example.com/de-store
* - If the visitor's country matches, they get the localized URL.
* - Everyone else gets the default destination.
*
* Country detection priority:
* 1. CloudFlare CF-IPCountry header (most reliable, free)
* 2. WordPress geo headers from hosting (e.g., Flavor, Flavor Starter)
*
* Uses the `gtlm_redirect_url` filter.
*/
defined( 'ABSPATH' ) || exit;
add_filter( 'gtlm_redirect_url', 'gtlm_geo_redirect', 10, 3 );
/**
* Override redirect URL based on visitor's country.
*
* @param string $url Default target URL.
* @param array $link Link data.
* @param string $slug Matched slug.
* @return string Possibly modified URL.
*/
function gtlm_geo_redirect( string $url, array $link, string $slug ): string {
$notes = $link['notes'] ?? '';
if ( empty( $notes ) ) {
return $url;
}
// Parse geo:XX = URL from notes.
$geo_urls = [];
foreach ( explode( "\n", $notes ) as $line ) {
$line = trim( $line );
if ( preg_match( '/^geo:([A-Z]{2})\s*=\s*(.+)$/i', $line, $m ) ) {
$geo_urls[ strtoupper( $m[1] ) ] = esc_url_raw( trim( $m[2] ) );
}
}
if ( empty( $geo_urls ) ) {
return $url;
}
// Detect country.
$country = gtlm_geo_detect_country();
if ( ! $country ) {
return $url;
}
return $geo_urls[ $country ] ?? $url;
}
/**
* Detect the visitor's country code (ISO 3166-1 alpha-2).
*
* @return string|null Two-letter country code or null.
*/
function gtlm_geo_detect_country(): ?string {
// CloudFlare (free tier).
if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) {
$code = strtoupper( sanitize_text_field( $_SERVER['HTTP_CF_IPCOUNTRY'] ) );
if ( strlen( $code ) === 2 && $code !== 'XX' ) {
return $code;
}
}
// Some hosts provide geo headers.
$headers = [ 'HTTP_X_COUNTRY_CODE', 'GEOIP_COUNTRY_CODE', 'HTTP_X_GEO_COUNTRY' ];
foreach ( $headers as $header ) {
if ( ! empty( $_SERVER[ $header ] ) ) {
$code = strtoupper( sanitize_text_field( $_SERVER[ $header ] ) );
if ( strlen( $code ) === 2 ) {
return $code;
}
}
}
return null;
}How It Works
- Uses the
gtlm_redirect_urlfilter to modify the target URL before redirect - Parses
geo:{COUNTRY_CODE} = {url}lines from the link’s Notes field - Detects the visitor’s country using (in priority order): CloudFlare
CF-IPCountryheader,X-Country-Codeheader,GEOIP_COUNTRY_CODEserver variable,X-Geo-Countryheader - Returns the matching country’s URL, or the default URL if no match is found
Configuration Notes
CloudFlare’s free tier automatically adds the CF-IPCountry header to every request, making it the easiest and most reliable option for country detection. No additional CloudFlare configuration is needed.
You can combine geo-based and role-based redirects on the same link by adding both geo: and role: lines in the Notes field. The geo filter runs at the default priority, so you can control execution order if needed.
Geo targeting is one of the few cases where Amazon affiliates genuinely need it; combine it with UTM passthrough so campaign data survives the country split. The underlying filter is documented in hooks and filters.