Сохранение UTM меток на ссылках текущей страницы

29 ноября 2022
Потребовалось, чтобы при заходе пользователя на сайт из поисковой или рекламной системы на внутренних переходах сохранялись UTM метки. На форумах был взят готовый код, который с некоторой доработкой и оптимизацией оформился в функцию add_dynamic_utm_to_links. Функция обходит все элементы-ссылки <a> и если ссылка принадлежит текущему сайту, то к адресу добавляются UTM-метки, которые есть в адресе текущей страницы.

Проверяются и добавляются следующие UTM-метки:
utm_medium
utm_source
utm_campaign
utm_term

Код функции:
/**
 * Функция обходит все элементы <a> и добавляет к ссылкам UTM-метки, которые пришли из текущего запроса 
 */
function add_dynamic_utm_to_links()
{
    //Домен, ссылки которого будут обработаны
    var domains_for_check = [
        '//' + window.location.hostname
    ];
 
    //Список UTM-меток, которые будут добавлены к ссылкам
    var utm_params = [
        'utm_medium',
        'utm_source',
        'utm_campaign',
        'utm_term'
    ];
 
    //Готовим строку, состоящую из utm-меток. Строка будет добавлена к ссылкам
    var ar = [];
    var str_utm_get_params = '';
    for (var index = 0; index < utm_params.length; index++){
        let utm_name = utm_params[index];
        let match = '';
        let value = '';
                    
        if (match = (new RegExp('[?&]' + encodeURIComponent(utm_name) + '=([^&]*)')).exec(window.location.search)){
            value = decodeURIComponent(match[1]);
        }
    
        if (value != '') {
            ar.push(utm_params[index] + '=' + value);
        }
    }
    str_utm_get_params = ar.join('&');
 
    //Если utm-меток нету, то завершаем работу функции
    if (str_utm_get_params == '') return false;
 
    //Массив всех ссылок страницы
    var links = document.querySelectorAll('a:not(.utm_checked)'); 
 
    //Обходим все ссылки и для подходящих добавляем строку, содержащую utm-параметры
    var connect_sign = '?';
    for (var index = 0; index < links.length; index++){
        //Если ссылка уже обработана, то пропускам её повторную обработку
        if (links[index].classList.contains('utm_checked') == true) continue;

        for (var d_num = 0; d_num < domains_for_check.length; d_num++){ 
 
            if (links[index].href.indexOf(domains_for_check[d_num]) > -1 && links[index].href.indexOf('#') === -1){
                //Символ для соединения параметров
                connect_char = '?';
                if(links[index].href.indexOf('?') > -1) {
                    connect_char = '&';
                }
 
                links[index].href = links[index].href + connect_char + str_utm_get_params;
            }
        }

        //Фиксируем обход ссылки с помощью css-класса
        links[index].classList.add('utm_checked');
    }

    return true;
}