Martech Zone is often a pass-through site where we connect our visitors with products, solutions, and services available through other sites. We don’t ever want our site utilized as a backlink farm by SEO consultants, so we’re pretty careful in the content we accept and how we redirect our visitors.
Where we can’t monetize an external referring link, we avoid passing any authority to the destination. Again, I don’t want this site ever seen by a search engine as a site where we’re trying to game search engines on behalf of a client or being paid to backlink by an unscrupulous backlinker. Every day we turn down money to do this because the result would spell disaster for my search engine rankings, the trust I’ve built with our readers, and… ultimately… the site’s value.
WordPress Redirects
To manage this process, I utilize Rank Math Pro’s redirection capabilities. It enables me to categorize a redirect to the destination page I want and tracks how much traffic I’m actually sending to the destination. Whether a destination is monetized through a referral link (like the Rank Math link I just shared) or sending traffic without an affiliate link, it enables me to organize, track, and create strategies around the traffic I’m sending.
One of the disadvantages of this is that companies may not be monitoring referral sites within Google Analytics since they could have thousands of sites sending them traffic. Since I’d like to get their attention as a good source of strong traffic, I’d like to append UTM parameters to a campaign querystring so that Martech Zone doesn’t just appear in their referring sites but in campaign tracking within Google Analytics.
This way, a company may see how much they’re spending on other campaigns and see the value in possibly building a partnership through a partnership or sponsorship with Martech Zone.
Add a UTM Querystring To Redirects
Below is a complete solution that appends custom UTM parameters to all WordPress redirects. It ensures that:
- utm_source = current page’s title (fallback: site name)
- utm_campaign =
"Redirect"
- utm_content = current page’s URL (fallback: site URL)
It uses sessions to capture the page-specific values. If the session is unavailable, it applies fallback defaults in the redirect. This helps you track, for sales and marketing, exactly which page redirected visitors off-site.
Step 1: Start a PHP Session
In your theme’s functions.php
or a small custom plugin:
add_action( 'init', function() {
if ( ! session_id() ) {
session_start();
}
});
This ensures WordPress can store and retrieve data in $_SESSION
.
Step 2: Capture Page Info on Each Page Load
Use add_action('wp')
to capture the current page’s name and URL. If the page is missing a title (or it’s a special route), fallback to the site name and home URL. Store these as a pre-built UTM query string in the session so it’s ready for any future redirects.
add_action( 'wp', function() {
// Only run on the public front-end (not in wp-admin)
if ( ! is_admin() ) {
// Check if the main query has at least one post/page
if ( have_posts() ) {
the_post(); // Prepare get_the_title(), get_permalink()
rewind_posts(); // Reset for the main loop if needed
// Grab the current page title and URL
$page_title = get_the_title();
$page_url = get_permalink();
// Site-level fallbacks
$site_name = get_bloginfo('name');
$home_url = home_url();
// If the page title is empty, use the site name
if ( empty( $page_title ) ) {
$page_title = $site_name;
}
// If the page URL is empty, use the home URL
if ( empty( $page_url ) ) {
$page_url = $home_url;
}
// Build a set of parameters:
// utm_source = page title (fallback: site name)
// utm_campaign = "Redirect"
// utm_content = page URL (fallback: site/home URL)
$utm_params = [
'utm_source' => $page_title,
'utm_campaign' => 'Redirect',
'utm_content' => $page_url
];
// Store them in the session as a pre-built query string
$_SESSION['utm_querystring'] = http_build_query( $utm_params );
}
}
});
If you only want to capture the first page a user visits (rather than updating it every time they move around), then only set $_SESSION['utm_querystring']
if it’s empty. That way, you don’t overwrite it on subsequent pages.
Step 3: Append the UTM Parameters During Redirects
In the wp_redirect
filter, we:
- Parse the existing destination URL and any existing query params.
- Fetch our session-based UTM parameters if they exist.
- If they don’t exist (session empty), use fallback defaults.
- Append only the UTM parameters that are missing in the destination.
add_filter( 'wp_redirect', 'my_session_based_utm_redirect_with_fallback', 10, 2 );
function my_session_based_utm_redirect_with_fallback( $location, $status ) {
// Skip if we're in the admin or if the location is empty
if ( is_admin() || ! $location ) {
return $location;
}
// Process only 3xx (redirect) status codes
if ( $status >= 300 && $status < 400 ) {
// Parse the existing destination URL
$parsed_url = parse_url( $location );
if ( ! isset( $parsed_url['host'] ) ) {
// If there's no valid host, we can't append
return $location;
}
// Parse any existing query parameters
$existing_params = [];
if ( isset( $parsed_url['query'] ) ) {
parse_str( $parsed_url['query'], $existing_params );
}
// --------------------------
// 1) GET SESSION-BASED UTM
// --------------------------
$session_utm_params = [];
if ( ! empty( $_SESSION['utm_querystring'] ) ) {
parse_str( $_SESSION['utm_querystring'], $session_utm_params );
}
// --------------------------
// 2) DEFINE FALLBACKS
// --------------------------
// If the session is empty or missing something, fallback to defaults.
$site_name = get_bloginfo( 'name' );
$site_url = home_url();
if ( empty( $session_utm_params['utm_source'] ) ) {
$session_utm_params['utm_source'] = $site_name;
}
if ( empty( $session_utm_params['utm_campaign'] ) ) {
$session_utm_params['utm_campaign'] = 'Redirect';
}
if ( empty( $session_utm_params['utm_content'] ) ) {
$session_utm_params['utm_content'] = $site_url;
}
// --------------------------
// 3) MERGE ANY MISSING UTM
// --------------------------
$utm_updated = false;
foreach ( $session_utm_params as $key => $val ) {
// If the destination doesn't already have a value for this param, append it
if ( empty( $existing_params[$key] ) ) {
$existing_params[$key] = $val;
$utm_updated = true;
}
}
// If we updated any param, rebuild the final URL
if ( $utm_updated ) {
$new_query = http_build_query($existing_params);
// Reconstruct the URL with updated query string
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
$location = sprintf(
'%s%s%s%s?%s%s',
$scheme,
$host,
$port,
$path,
$new_query,
$fragment
);
}
}
// Return the (possibly) modified location
return $location;
}
How It Helps Marketing & Sales
- Per-Page Attribution: You see exactly which page drove a user to an external site via
utm_source
, giving you more accurate campaign and referral analytics. - Distinct Campaign: By using
"Redirect"
inutm_campaign
, you can segment all externally driven traffic in your analytics platform. - Custom Content Tag: With
utm_content
set to the exact page URL, you can measure precisely which pages drive the most outbound traffic.
Optional: Only Tag External Links
If you only want to tag outbound links (not internal redirects), add a quick check:
$site_url = site_url();
if ( strpos( $location, $site_url ) === 0 ) {
// It's an internal link, so skip
return $location;
}
Place that right after you parse $location
. This ensures you only tag links that lead off your domain.
Summary
- Start Session – needed for capturing page-specific data.
- Capture Page Info – store the page title and URL in the session (fallback: site name and site URL).
- Append UTM – in
wp_redirect
, parse the destination and only add the UTM parameters if they’re missing. If there’s no session data, rely on the same fallback defaults so you always have something.
This complete approach ensures you’ll see in your analytics something like:
https://destination.com/
?utm_source=Your+Page+Title
&utm_campaign=Redirect
&utm_content=https%3A%2F%2Fyourdomain.com%2Fyour-page
Every time a user is redirected from your site, your sales and marketing reporting can accurately attribute which pages (and which campaign) drove the outbound clicks.
©2024 DK New Media, LLC, All rights reserved | Disclosure
Originally Published on Martech Zone: WordPress: How To Append A UTM Campaign Querystring To External Redirects