Geo-Based Redirects

  • KPrevious lesson
  • FSearch lessons
  • EscClear search

Redirect visitors to different destination URLs based on their geographic location. A single short link can send US visitors to your American store, UK visitors to your British store, and everyone else to the default destination. Works best with CloudFlare (free tier provides country detection).

Requirements

  • GT Link Manager 1.5+ installed and active
  • CloudFlare (free tier is sufficient) for automatic country detection via the CF-IPCountry header, OR a hosting provider that sets geo headers

Installation

  • Add the snippet below to your theme’s functions.php or 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_url filter 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-IPCountry header, X-Country-Code header, GEOIP_COUNTRY_CODE server variable, X-Geo-Country header
  • 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.