How to Build a Simple UTM System to Track Your Ad Campaigns

Diogo MachadoDiogo Machado
2 min read

Motivation

I'm building my microsaas, and since I'm not a marketing specialist, it is difficult for me to validate if the money invested brings a return or not. For example, I tried TikTok Ads, YouTube, and Google Ads, but the reports from these services are complex and difficult. So, as I'm using a local Metabase to manage my data, I had a simple idea, which I explain below in an image.

The idea

With this idea, you can implement it in any front-end stack. In my case, I'm using Angular, so I'll show you how I did it:

  1. Create a service

  2. Listen the URL changes

  3. Save the UTM params in the localStorage

  4. Get the UTM params and send to the API

The service

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UtmService {
  private readonly utmKeys = [
    'utm_id',
    'utm_source',
    'utm_medium',
    'utm_campaign',
    'utm_term',
    'utm_content',
  ];
  private readonly sessionKey = 'NAME-YOUR-SESSION';

  constructor() {}

  saveUtmsFromQuery(params: any): void {
    const utms: any = {};

    this.utmKeys.forEach((key) => {
      if (params[key]) {
        utms[key] = params[key];
      }
    });

    if (Object.keys(utms).length) {
      localStorage.setItem(this.sessionKey, JSON.stringify(utms));
    }
  }

  getUtms(): any {
    const data = localStorage.getItem(this.sessionKey);
    return data ? JSON.parse(data) : null;
  }

  clearUtms(): void {
    localStorage.removeItem(this.sessionKey);
  }
}

Inject the service in the AppComponent:

utmService = inject(UtmService);

In the ngOnInit(), I created a method:

ngOnInit(): void {
    this.listenQueryParams();
}
listenQueryParams() {
    this.route.queryParams.subscribe((params) => {
      this.utmService.saveUtmsFromQuery(params);
    });
  }

Sending the data to your API

This part depends on your backend API. In my case, I made changes to send the data when the user creates a new event. Collecting the UTM is simple:

constructor(
    private fb: FormBuilder,
  ) {
    this.myForm = this.fb.group({
      email: ['', [Validators.required, Validators.email]],
      password: ['', [Validators.required, Validators.minLength(6)]],
      utm_source: [null],
      utm_medium: [null],
      utm_campaign: [null],
      utm_term: [null],
      utm_content: [null],
    });

    this.myForm.patchValue(this.utmService.getUtms());
  }

Now, when I send the form data, the UTM goes along automatically.

That's it ๐ŸŽ‰

0
Subscribe to my newsletter

Read articles from Diogo Machado directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Diogo Machado
Diogo Machado