Jetpack: add UTM tracking to sharing buttons

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 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 plugin in the repo if you’re interested in implementing 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
 * @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 URL redirecting to the full URL with tracking parameters.
		 * @see
		 * This uses my own API key by default.
		 * if you want to use your own to have stats attached to your own account,
		 * get your own key here:
		$googl_key = 'my_api_key';

		// Let's query Google and get a Short URL
		$googl_result = wp_remote_post(
				'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 );