Quantcast
Channel: Martech Zone
Viewing all articles
Browse latest Browse all 1361

WordPress: How To Append A UTM Campaign Querystring To External Redirects

$
0
0

Append Google ANalytics UTM Campaign Querystring to Redirects

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:

  1. utm_source = current page’s title (fallback: site name)
  2. utm_campaign = "Redirect"
  3. 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:

  1. Parse the existing destination URL and any existing query params.
  2. Fetch our session-based UTM parameters if they exist.
  3. If they don’t exist (session empty), use fallback defaults.
  4. 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" in utm_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

  1. Start Session – needed for capturing page-specific data.
  2. Capture Page Info – store the page title and URL in the session (fallback: site name and site URL).
  3. 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


Viewing all articles
Browse latest Browse all 1361

Trending Articles