“I know I waste half of my advertising dollars...I just wish I knew which half.” said Henry Procter.
Knowing where your site signups come from is a good way of knowing if you are spending your advertisement dollars on the right target, but how would you do that?
Google Analytics is the most common tool used by many for that. The problem is Google Analytics can become very complicated very quickly. More importantly linking a campaign with a single signup is something that should happen in the app during the signup process. This will mark each individual user with the campaign they came from.
Mark your campaigns
Started by Google Analytics, UTM
parameters in URLs were created to link campaigns to visits, but they are not limited to Google Analytics and are supported by almost any visitor tracking utility out there.
To start with, make sure all the links coming to your website use UTM parameters. You can use Google Analytics URL Builder or just simply add utm_source
and utm_campaign
to the URL coming to your site. This will end up looking something like this:
http://www.mysite.com?utm_source=test&utm_campaign=promo
Capture the UTM into a cookie
Not every one who visits the site is going to signup immediately, but they might do that later, so we need a way to capture that.
To achieve that, we are going to capture the utm
parameters into a cookie that expires in a month. That way if the visitor signs up for up to a month, we know where he came from.
In Rails, we can do that by a filter:
before_filter :capture_utm
private
def capture_utm
unless cookies[:utm]
cookies[:utm] = { :value => utm.to_json, :max_age => "2592000" }
end
end
def utm
{
:utm_source => params[:utm_source],
:utm_campaign => params[:utm_campaign],
:utm_medium => params[:utm_medium],
:utm_term => params[:utm_term],
:utm_content => params[:utm_content]
}
end
Read the cookie before signup
Linking the utm
parameters with the new user is easy. If you are using Devise to manage your users, you can customise the signup controller to capture the value:
class CustomRegistrationsController < Devise::RegistrationsController
def create
super
begin
utm = cookies[:utm]
if utm
resource.utm_params = utm
resource.save
end
rescue => exc
Rails.logger.error "Error reading utm cookie due to #{exc}"
end
Make sure you add this line to your routes.rb:
devise_for :users, :controllers => {:registrations => “custom_registrations” }
utm_params
is a text
field we added to the User
class in a migration. This will store the JSON serialised version of the utm
parameters in database next to each new signup.
You might want to avoid addin the values if they are empty (like when the signup came from no campaign) but I prefer having them there all the time to simplify reading and deserialising them during analysis.
What if you have multiple subdomains?
If you are like us, you don't only have 1 website. We have a blog (this one), help website. Also our main website www.cloud66.com is a separate app.
All of our apps are hosted on cloud66.com subdomains: blog.cloud66.com, help.cloud66.com and community.cloud66.com
This means we can use cookies that run across all of our websites. In Rails you can do this by adding domain
to the cookies.
This will change the capture_utm
method above to this one:
def capture_utm
unless cookies[:utm]
cookies[:utm] = { :value => utm.to_json, :max_age => "2592000", :domain => ".mydomain.com" }
end
end
Note the .
before the domain name. Using this method the cookies will be sent to the main app (where the signup happens) regardless of where the first visit was.
How about CDN?
We also use AWS Cloudfront as a CDN for our main website. This speeds up requests and reduces load on our servers. We use custom origin servers for our Cloudfront but the default settings is not going to work with the solution above.
This is because Cloudfront CDN by default ignores query strings and doesn't forward cookies to the origin server. Solving this is simple!
Login to your AWS Cloudfront dashboard and select the Cloudfront distribution. Under Behaviors, you can select edit and change these two settings:
Forward Query Strings
to yes
andForward Cookies
to all
Done!