Geo-Based Redirects in GT Link Manager
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. Since version 1.7.0, GT Link Manager ships this as a built-in feature, so start there. This lesson covers when the built-in rules are the right tool, and keeps the original code snippet for anyone on an older version or with detection needs the built-in methods don’t cover.
Use the built-in feature first
GT Link Manager 1.7.0 added native geolocation targeting: enable it in GT Links → Settings, then build country rules per link in a visual rule builder with ordered rules, one-click market presets, an EU group covering all 27 member states, per-rule status codes, and a rule preview. No code required. The geolocation targeting lesson covers it end to end.
The built-in feature replaces this snippet for nearly every use case. Reach for the snippet below only if you’re pinned to a pre-1.7.0 version, or you need country detection from a source the plugin’s methods and the gtlm_geo_country filter can’t reach.
Requirements
- GT Link Manager 1.5+ installed and active (on 1.7.0+, prefer the built-in feature above)
- 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-store
Use 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 adds the CF-IPCountry header on every plan, which makes it the easiest and most reliable option for country detection. It only arrives when IP Geolocation is on for the zone. If the header is missing, turn it on under Rules → Settings or Network → IP Geolocation. GT Link Manager’s Detected Now readout in Settings tells you when this is the cause.
You can combine geo-based and role-based redirects on the same link by adding both geo: and role: lines in the Notes field. Both snippets register at priority 10 and return a fresh URL, so whichever runs last wins. Give the one that should have the final say a later priority, and run UTM passthrough after both, at 20.
One more thing if you use this snippet: keep the link on 302, not 301. Browsers cache a 301 permanently, so a returning visitor stays pinned to whichever country they were in on their first click.
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, and the built-in feature lives in the geolocation targeting lesson.