Jetpack: add UTM tracking to sharing buttons

in Work

After figuring out a nice little challenge in the Jetpack support forums last week, I wanted to share the results with you.

First of all, I need to thank Aquif Shaikh for his question in the original thread. This thread required a bit more digging than usual, and I love a good challenge.

The question was actually quite simple: how to add UTM tracking to the Jetpack sharing buttons. If you’re not familiar with UTM tracking, you’ll want to check this generator. UTM tracking allows you to track specific URLs in Google Analytics.

Let’s get started.

Jetpack offers a sharing_permalink filter. It seemed easy to add parameters to the existing permalinks. It turned out to be a bit more complicated than I thought, because of 2 issues:

  1. Twitter, Google+, and possibly other Social Networks appear to strip exact GET parameters from URLs when you use their sharing tools. To work around this, I decided to send short URLs instead of the original permalink and the UTM tracking parameters. To do this, I used goo.gl. It’s still one of my favorite URL shorteners (when you don’t use your own, and Google offers a good set of instructions to help you use their APIs. My colleague Konstantin also released a Goo.gl plugin in the repo if you’re interested in implementing Goo.gl on your site.
  2. Google Analytics didn’t really like the encoded ampersands in the URLs I created, and didn’t track the campaigns properly.

Here is the final, commented code. Leave a comment if you have questions, or have a better idea to solve this issue!

/**
 * Overwrite the links used in Jetpack's Sharing module.
 *
 * @see https://wordpress.org/support/topic/how-to-use-utm-codes-with-jetpack-sharing
 *
 * @param string $url
 * @param int $post_id
 * @param int $sharing_id
 * @filter sharing_permalink
 * @return string
 */
function jeherve_custom_sharedaddy_link( $url, $post_id, $sharing_id ) {

	// Let's see if we have a shortlink for this post
	$tracked_url = get_post_meta( $post_id, '_tracked_googl_shortlink', true );

	if ( $tracked_url ) {
		return $tracked_url;
	} else {
		// Let's build our tracking parameters
		$ga_params = array(
			'utm_source'   => $sharing_id,
			'utm_medium'   => 'XXX',
			'utm_term'     => 'XXX',
			'utm_content'  => 'XXX',
			'utm_campaign' => 'XXX',
		);

		// Add them to our post permalink
		$tracked_url = esc_url( add_query_arg( $ga_params, $url ) );

		// Do not encode ampersands, GA doesn't like it.
		$tracked_url = str_replace( '&', '&', $tracked_url );

		/**
		 * Create a short Goo.gl URL redirecting to the full URL with tracking parameters.
		 *
		 * @see https://goo.gl/
		 *
		 * This uses my own API key by default.
		 * if you want to use your own to have stats attached to your own Goo.gl account,
		 * get your own key here: https://developers.google.com/url-shortener/v1/getting_started?hl=en
		 */
		$googl_key = 'my_api_key';

		// Let's query Google and get a Short URL
		$googl_result = wp_remote_post(
			add_query_arg(
				'key',
				$googl_key,
				'https://www.googleapis.com/urlshortener/v1/url'
			),
			array(
				'body' => json_encode( array( 'longUrl' => esc_url_raw( $tracked_url ) ) ),
				'headers' => array( 'Content-Type' => 'application/json' ),
			)
		);

		// Return the default URL if the request got an error.
		if ( is_wp_error( $googl_result ) ) {
			return esc_url( $url );
		}

		$googl_result = json_decode( $googl_result['body'] );
		$googl_link = $googl_result->id;

		if ( $googl_link ) {
			// Let's save that in post meta for the next call
			add_post_meta( $post_id, '_tracked_googl_shortlink', $googl_link, true );

			// And boom! return a short tracked URL.
			return $googl_link;
		} else {
			return esc_url( $url );
		}

		// Final default, just in case
		return esc_url( $url );
	}
}
add_filter( 'sharing_permalink', 'jeherve_custom_sharedaddy_link', 10, 3 );