Skip to content

WooCommerce UTM Tracking – Step by step guide

You’ve probably wondered before how did a specific customer find your website. Now we can find out for each order! We will use the UTM tags (or the referrer, if UTM parameters are not available) to track their visits and send this data as a custom field in WooCommerce.

There are 2 main parts to achieving this goal:

Capture the UTM parameters

While this is possible with Javascript code snippets on your website, I opted to use Google Tag Manager (GTM) as I need this solution on other websites too, where I don’t have access to edit the code. In addition, I can make use of Google Tag Manager’s user-defined variables.

Google Tag Manager variables

First, we’ll need to create the following user-defined variables in Google Tag Manager to capture the UTM parameters. If there are no UTM parameters, then we’ll default to using the referrer, if available and if it’s an external website.

Please use these exact names, as the custom HTML tag would not work if they’re different.

  • url - utm_source variabile captures the value of the utm_source parameter.
  • url - utm_medium variabile captures the value of the utm_medium parameter.
  • url - utm_campaign variabile captures the value of the utm_campaign parameter.
  • url - hostname variabile will return the hostname of your website. We need this to exclude sending the referrer if it’s internal traffic (when users are navigating on multiple pages of your website)
  • referrer - full variabile is used as the source whenever there are no UTM parameters available.

Custom HTML tag to capture the UTM parameters

Next, we need to create a custom HTML tag that captures the UTM parameters (or the referrer, if no UTM tags are available) and saves it into the sessionStorage. Paste the following code snippet:

  var source = sessionStorage.getItem('source');
  if ({{url - utm_source}}) {
    source = {{url - utm_source}} + ' / ' + {{url - utm_medium}} + ' / ' + {{url - utm_campaign}};
    sessionStorage.setItem('source', source);
  else if ((!source) || (source == 'none')) {  
    if (({{referrer - full}}) && (!{{referrer - full}}.includes('{{url - hostname}}'))) {
      source = {{referrer - full}} + ' / referral';
      sessionStorage.setItem('source', source);
    else {
      source = 'none';
      sessionStorage.setItem('source', source);
</script>Code language: HTML, XML (xml)

I named my tag cHTML - source to sessionStorage, but you can freely change it if you prefer. It should look like this:

GTM Tag to capture the UTM parameters and save them in the sessionStorage

The logic is as follows:

  • if there are UTM parameters, we’ll save the source as utm_source / utm_medium / utm_campaign
  • if there are no UTM tags, if there is a referrer (e.g. visitor came from an external website), save the source as / referral
  • if there are no UTM tags and no referrer, set the source as none. I set this default value to be able to tell apart cases when the code does not run correctly for some reason, in which case we expect the source to be empty (or undefined).

Send the UTM tags in WooCommerce orders

Now that we have the UTM tags saved in the session storage, we can send it further to WooCommerce orders as a custom field. In order to achieve this, we have to add a hidden field on the checkout page, then pass the value of the UTM tags to it.

Create a hidden field on the WooCommerce checkout page

I chose to use a code snippet to create a hidden field on the WooCommerce checkout page. There might be plugins that are able to achieve this without code, but it would’ve been an overkill for my needs.

Too add a hidden field on your WooCommerce checkout page, add the following code snippet to your website:

// Add a hidden field on the checkout page
add_action('woocommerce_after_order_notes', 'checkout_source_field');

function checkout_source_field( $checkout ) {
	woocommerce_form_field( 'my_source_field', array( 
		'type' 			=> 'text',
		'required'		=> false,
		'placeholder' 	=> __('utm_source'),
		), $checkout->get_value( 'my_source_field' ));

// Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'checkout_source_field_update_order_meta');

function checkout_source_field_update_order_meta( $order_id ) {
	if ($_POST['my_source_field']) update_post_meta( $order_id, 'Source', esc_attr($_POST['my_source_field']));
Code language: PHP (php)

If you use the Code Snippets plugin, it should look like this:

Add a hidden checkout field in WooCommerce

In the code snippet above, we will later replace the type from text to hidden. For now, we want the field to be visible, to make sure we are sending the right data.

Important! Do not change the value of my_source_field, as we’ll refer to this later.

Get the UTM tags in the WooCommerce checkout field

Back to Google Tag Manager, we’ll need to create a tag that only fires on the checkout page. It should get the value of the UTM parameters from the session storage and set it in the source field on the WooCommerce checkout page.

By default, the web address of the checkout page on a WordPress website is like this: I am going to assume this is the case for your website too. If not, you may have to adjust the trigger below accordingly.

Create a DOM Ready trigger on the checkout page

The reason why we use DOM Ready instead of Page View is that it fires a bit later. This way, we are sure that when we execute the code to set the value of the source field (on DOM Ready), the code that saves the source in the session storage has already been executed.

The condition we will use to match the checkout page only is: Page Path equals /checkout/. Feel free to adjust this condition if your checkout page has a different address.

I named my trigger DOM - checkout page. After setting the condition, the trigger should look like this:

Create a Tag that sends the UTM parameters in your WooCommerce checkout field

Create a custom HTML tag that firest on the trigger we just created. Paste the following code snippet in your tag:

    // sets the source (UTM parameters) as the value of the hidden checkout field
  document.querySelector("#my_source_field").value = sessionStorage.getItem('source');
</script>Code language: HTML, XML (xml)

I’ve named my tag cHTML - source to woocommerce. If you’ve named yours the same, it should look like this:

Get the UTM tags and set it as WooCommerce checkout field

Either in Preview mode of GTM or after you publish the container, visit your website and add the following parameters at the end of the URL: ?utm_source=test_source&utm_medium=test_medium&utm_campaign=test_campaign.

If you want to see how this works on my website, you can visit

Add a product to your cart and go to the checkout page. At the bottom of checkout page, you should be able to locate this extra field with the value test_source / test_medium / test_campaign.

Send the UTM tags to WooCommerce checkout

This field is visible on purpose, for debugging. When you are done testing, remember to change this value from text to hidden.

Once you place the order, you will not notice anything different. That’s intended, as the source should be visibile to the website owner, not to the customer. Going into the WordPress admin dashboard to edit the order, we can now see the value of the source field as in this screenshot.

That’s it! You have successfully taken the source of the visit (either UTM parameters or the referrer) and sent it to your WooCommerce orders.

2 thoughts on “WooCommerce UTM Tracking – Step by step guide”

  1. This is great!

    Is it possible to modify so that the variables go into different fields, instead of one field separated by the / ?

    1. Hi Luther,

      Yes. First, you would need to create multiple hidden fields on the WooCommerce checkout page, one for each UTM and make sure to give them different IDs (i.e. my_source_field).

      Second, you’d need to write in each of these fields individually. It can be in the same tag, but you would need to write the value in each field (one line as below for each UTM parameter):
      document.querySelector("#field_id").value = sessionStorage.getItem('utm_value');

Leave a Reply

Your email address will not be published. Required fields are marked *