Track redirect clicks as events in Matomo (formerly Piwik) using the HTTP Tracking API. This server-side integration gives you full click analytics in your self-hosted Matomo instance without requiring any client-side JavaScript.
Requirements
- GT Link Manager 1.5+ installed and active
- A Matomo instance (self-hosted or cloud)
- Your Matomo Site ID (Settings > Websites)
- (Optional) An auth token for enhanced tracking with IP and geo-location (Settings > Personal > Security > Auth tokens)
Installation
- Add the snippet below to your theme’s
functions.phpor a site-specific plugin - Set
GTLM_MATOMO_URLto your Matomo instance URL (no trailing slash) - Set
GTLM_MATOMO_SITE_IDto your Matomo Site ID - (Optional) Set
GTLM_MATOMO_TOKENfor IP-based geo-location tracking
The Code
<?php
/**
* GT Link Manager - Matomo (Piwik) Integration
*
* Tracks redirect clicks as events in Matomo via the HTTP Tracking API.
* Server-side — no JavaScript required.
*
* Setup:
* 1. Set your Matomo instance URL (no trailing slash)
* 2. Set your Site ID (visible in Matomo under Settings > Websites)
* 3. (Optional) Set an auth token for enhanced tracking (IP, location)
* Get it from Matomo: Settings > Personal > Security > Auth tokens
*
* Event category: "Redirect"
* Event action: "Link Click"
* Event name: Link name or slug
* Event value: Redirect HTTP status code
*
* @see https://developer.matomo.org/api-reference/tracking-api
*/
defined( 'ABSPATH' ) || exit;
// ── Configuration ────────────────────────────────────────────────────────────
define( 'GTLM_MATOMO_URL', 'https://matomo.example.com' ); // Matomo instance URL (no trailing /)
define( 'GTLM_MATOMO_SITE_ID', 1 ); // Matomo Site ID
define( 'GTLM_MATOMO_TOKEN', '' ); // Auth token (optional, for IP/geo)
// ─────────────────────────────────────────────────────────────────────────────
add_action( 'gtlm_before_redirect', 'gtlm_matomo_track_click', 10, 4 );
/**
* Send a tracking event to Matomo when a redirect fires.
*
* @param array $link Link data.
* @param string $target_url Destination URL.
* @param int $status HTTP status code.
* @param array $headers Response headers.
*/
function gtlm_matomo_track_click( array $link, string $target_url, int $status, array $headers ): void {
if ( GTLM_MATOMO_URL === 'https://matomo.example.com' ) {
return; // Not configured yet.
}
$request_url = home_url( sanitize_text_field( $_SERVER['REQUEST_URI'] ?? '/' ) );
$params = [
// Required.
'idsite' => GTLM_MATOMO_SITE_ID,
'rec' => 1,
// Page context.
'url' => $request_url,
'urlref' => sanitize_text_field( $_SERVER['HTTP_REFERER'] ?? '' ),
'action_name' => 'Redirect: ' . ( $link['name'] ?? $link['slug'] ?? '' ),
// Event tracking.
'e_c' => 'Redirect', // Event category
'e_a' => 'Link Click', // Event action
'e_n' => $link['name'] ?? $link['slug'] ?? 'unknown', // Event name
'e_v' => $status, // Event value
// Custom variables (slot 1-5 available).
'cvar' => wp_json_encode( [
'1' => [ 'Link Slug', $link['slug'] ?? '' ],
'2' => [ 'Target URL', mb_substr( $target_url, 0, 200 ) ],
'3' => [ 'Category ID', (string) ( $link['category_id'] ?? 0 ) ],
] ),
// Visitor context.
'ua' => sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] ?? '' ),
'lang' => sanitize_text_field( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '' ),
'rand' => wp_rand(),
'apiv' => 1,
// Generate a visitor ID from IP + UA for consistency.
'_id' => substr( md5( ( $_SERVER['REMOTE_ADDR'] ?? '' ) . ( $_SERVER['HTTP_USER_AGENT'] ?? '' ) ), 0, 16 ),
];
// Add client IP if auth token is set (required for accurate geo-location).
if ( ! empty( GTLM_MATOMO_TOKEN ) ) {
$params['token_auth'] = GTLM_MATOMO_TOKEN;
$client_ip = gtlm_matomo_get_client_ip();
if ( $client_ip ) {
$params['cip'] = $client_ip;
}
}
wp_remote_post(
trailingslashit( GTLM_MATOMO_URL ) . 'matomo.php',
[
'body' => $params,
'blocking' => false,
'timeout' => 1,
]
);
}
/**
* Get the real client IP.
*
* @return string|null
*/
function gtlm_matomo_get_client_ip(): ?string {
$headers = [ 'HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'REMOTE_ADDR' ];
foreach ( $headers as $header ) {
if ( ! empty( $_SERVER[ $header ] ) ) {
$ip = strtok( sanitize_text_field( $_SERVER[ $header ] ), ',' );
if ( filter_var( trim( $ip ), FILTER_VALIDATE_IP ) ) {
return trim( $ip );
}
}
}
return null;
}
How It Works
- Hooks into
gtlm_before_redirectto fire on every redirect - Sends event tracking data: category =
Redirect, action =Link Click, name = link name - Uses Matomo custom variables (slots 1-3) for link slug, target URL, and category ID
- Generates a consistent visitor ID from IP + User Agent for session tracking
- When an auth token is provided, sends the real client IP for accurate geo-location
Configuration Notes
Events appear in Matomo under Behaviour > Events. You can filter by the event category Redirect to see all link clicks. Custom variables are visible in Visitors > Custom Variables.
The auth token is optional but recommended for accurate geo-location data. Without it, Matomo will use the server’s IP instead of the visitor’s IP for location detection.