Yandex.Metrica and Google Analytics are both web analytics tools that help website owners and marketers track and analyze user behavior on their websites. While they serve similar purposes, there are some technical differences between the two:
Session Definition:
Both platforms define a "session" as a period of user activity on your website. However, the exact parameters that determine the start and end of a session might vary slightly.
Visit Attribution:
The attribution of visits to various sources (such as direct traffic, referrals, organic search, etc.) could be monitored and presented in distinct ways between Yandex.Metrica and Google Analytics. This variance can influence your comprehension of user acquisition and behavior, potentially leading to inconsistency between your historical reports and the new tracking system.
To ensure greater consistency in reports across the two different systems, we can implement a specific JavaScript code that establishes visit attribution, similar to the approach taken by Google Analytics.
Sourcebuster is a tool that monitors and records the origins of visitors to your website, preserving this data in cookies for subsequent analysis. It manages the overriding of sources in a manner similar to Google Analytics. Notably, it's crafted using pure JavaScript, devoid of any reliance on third-party libraries.
Yandex Metrika start counter code https://metrica.yandex.com/
<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(234289, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true
});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/46917844" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
The sourcebuster https://sbjs.rocks/. Lets separate code from the instruction on 2 parts
uploading part
<script src="/path/to/sourcebuster.min.js"></script>
initialisation part
<script>
sbjs.init({
callback: function callback() {
ym(234289, "params", getInitSB);
}
});
</script>
For our purpose we need to use next part of code to send parameters https://yandex.com/support/metrica/objects/params-method.html
ym(46917844, 'params', parameters);
We have to parse data from cookie to make it affordable for using in metrika UI report system
function getInitSB() {
var initObj = new Map();
var addSbToInit = function addSbToInit(initObj) {
var matches = document.cookie.match(/sbjs[^;]*/g);
if (matches != null) {
matches.forEach(function (element) {
var tgt = decodeURIComponent(element).split(/=([\s\S]*)/)[0];
decodeURIComponent(element)
.split(/=([\s\S]*)/)[1]
.split("|||")
.forEach(function (elem) {
return initObj.set(
tgt + "_" + elem.split("=")[0],
elem.split("=")[1]
);
});
});
}
};
addSbToInit(initObj);
return initObj.size == 0
? {init: 'sb_error'}
: {
init: Object.fromEntries(initObj)
};
}
Let's put it all together. The key concept here is that browsers and JavaScript operate asynchronously. This means that errors can occur while running a script because different parts might not have completed their tasks yet. To prevent such errors, we follow a specific order when placing code on the page.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="google analytics attribution">
<meta name="author" content="Dmitriy Yugin">
<meta name="generator" content="">
<title>Attribution establishing</title>
<script src="/path/to/sourcebuster.min.js"></script>
<script>
function getInitSB() {
var initObj = new Map();
var addSbToInit = function addSbToInit(initObj) {
var matches = document.cookie.match(/sbjs[^;]*/g);
if (matches != null) {
matches.forEach(function (element) {
var tgt = decodeURIComponent(element).split(/=([\s\S]*)/)[0];
decodeURIComponent(element)
.split(/=([\s\S]*)/)[1]
.split("|||")
.forEach(function (elem) {
return initObj.set(
tgt + "_" + elem.split("=")[0],
elem.split("=")[1]
);
});
});
}
};
addSbToInit(initObj);
return initObj.size == 0
? {init: 'sb_error'}
: {
init: Object.fromEntries(initObj)
};
}</script>
<head>
<body>
/*some html page code*/
<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(234289, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true
});
sbjs.init({
callback: function callback() {
ym(234289, "params", getInitSB);
}
});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/46917844" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
</body>