Skip to content

Instantly share code, notes, and snippets.

@joostvanhoof
Last active March 16, 2021 22:47
Embed
What would you like to do?
Feather Attribution script
// www.featherattribution.com. Brought to you by www.scrapingbee.com and www.freddyfeedback.com
class FeatherAttribution {
constructor(options) {
this.storageItems = ['feather_utm_source', 'feather_utm_medium', 'feather_utm_campaign', 'feather_utm_content', 'feather_ref', 'feather_referrer'];
this.checkExpiryDates();
this.setOptions(options);
this.referrer = document.referrer;
this.ref = this.getParameterByName('ref');
this.utm_source = this.getParameterByName('utm_source');
this.utm_medium = this.getParameterByName('utm_medium');
this.utm_campaign = this.getParameterByName('utm_campaign');
this.utm_content = this.getParameterByName('utm_content');
this.setAllLocalStorageItems();
}
checkExpiryDates() {
this.storageItems.forEach(element => {
const item = localStorage.getItem(element);
const now = new Date();
if(item) {
const itemDetails = JSON.parse(item);
if (now.getTime() > itemDetails.expiry) {
localStorage.removeItem(element);
}
}
});
}
setOptions(options) {
if (typeof options !== "undefined") {
options.hasOwnProperty('expires_in_days') ? this.expires_in_days = options.expires_in_days : 30;
options.hasOwnProperty('attribution_type_utm') ? this.attribution_type_utm = options.attribution_type_utm : 'first';
options.hasOwnProperty('attribution_type_ref') ? this.attribution_type_ref = options.attribution_type_ref : 'first';
options.hasOwnProperty('attribution_type_referrer') ? this.attribution_type_referrer = options.attribution_type_referrer : 'last';
} else {
this.expires_in_days = 30;
this.attribution_type_utm = 'first';
this.attribution_type_ref = 'first';
this.attribution_type_referrer = 'last';
}
const now = new Date();
this.expires_on = now.getTime() + (86400000 * this.expires_in_days);
}
getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
var results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
truncateString(string) {
if (string.length < 255) {
return string;
}
return string.substring(0, 255);
}
setLocalStorage(key, value, attribution_type) {
if(!value) {
return;
}
const item = {
value: this.truncateString(value),
expiry: this.expires_on,
}
if(attribution_type == 'last') {
localStorage.removeItem(key);
localStorage.setItem(key, JSON.stringify(item));
}
if(attribution_type == 'first' && this.getLocalStorage(key) == null) {
localStorage.setItem(key, JSON.stringify(item));
}
}
getLocalStorage(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) {
return null;
}
const item = JSON.parse(itemStr);
return item.value;
}
setAllLocalStorageItems() {
this.setLocalStorage('feather_utm_source', this.utm_source, this.attribution_type_utm);
this.setLocalStorage('feather_utm_medium', this.utm_medium, this.attribution_type_utm);
this.setLocalStorage('feather_utm_campaign', this.utm_campaign, this.attribution_type_utm);
this.setLocalStorage('feather_utm_content', this.utm_content, this.attribution_type_utm);
this.setLocalStorage('feather_ref', this.ref, this.attribution_type_ref);
this.setLocalStorage('feather_referrer', this.referrer, this.attribution_type_referrer);
}
fillFieldsWithValues() {
this.fillSingleFieldWithValue('utm_source', 'feather_utm_source');
this.fillSingleFieldWithValue('utm_medium', 'feather_utm_medium');
this.fillSingleFieldWithValue('utm_campaign', 'feather_utm_campaign');
this.fillSingleFieldWithValue('utm_content', 'feather_utm_content');
this.fillSingleFieldWithValue('ref', 'feather_ref');
this.fillSingleFieldWithValue('referrer', 'feather_referrer');
}
fillSingleFieldWithValue(field, value) {
if(document.getElementById(field)) {
document.getElementById(field).value = this.getLocalStorage(value);
} else {
console.warn('Can not find the field with id = ' + field);
}
}
}
window.featherAttribution = new FeatherAttribution({
expires_in_days: 30,
attribution_type_utm: 'first',
attribution_type_ref: 'first',
attribution_type_referrer: 'last'
});
@johnhearfield
Copy link

Would you consider the idea of automatically adding the hidden input fields to every form on the page if the UTM parameters are detected? This plugin does that and a few more: https://github.com/medius/utm_form

@joostvanhoof
Copy link
Author

This script will not be under active development as it was a (very small) side project. Feel free to copy paste the snippet and change it as you like!

If fields are auto-added I’d do it by a class selector on the form. This way you can specify for each form whether you want to the forms auto-added. A second option would be to give the script an extra option parameter to set whether auto-adding is on or off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment