Adaptive Mind

Archive for the ‘Practical Tips’ Category

Warning: this is pretty heavy JavaScript stuff.

If you’d ask what the most used web analytics solution is, you would probably get pretty obvious answer. But what is not so obvious to the most people who use Google Analytics is the fact that it is a piece of JavaScript and it can be customized a lot. Especially these days when we measure dynamic websites full of JavaScript features that stay hidden to the basic generated tracking script.

Frontend developers got used to benefit from JavaScript libraries like jQuery that help them not to write repetitive code, resolve a lot of cross-browsers issues and achieve a better maintainability of their code. And as I said before, Google Analytics Tracking Code (GATC) is just another piece of JavaScript that you include into your website, so why wouldn’t you give it the same treatment as to the rest of the scripts.

A little optimized basic asynchronous tracking script (Google recommends to put it into your document’s <head> section as an inline script):

var _gaq = [];

_gaq.push(

       ['_setAccount', 'UA-XXXXXX-X'],   // doplnit vlastní ID účtu

       ['_trackPageview']

);

 

(function (d, t) {

       var g = d.createElement(t),

             s = d.getElementsByTagName(t)[0];

       g.async = 1;

       g.src = ("https:" === d.location.protocol ? "https://ssl" : "http://www");

       g.src += ".google-analytics.com/ga.js";

       s.parentNode.insertBefore(g, s);

}(document, "script"));

With this article I would like to start a series of implementation tips that should help you to make the most of Google Analytics implementation using the features of the most popular JavaScript library jQuery.

Prerequisites

And when I say that the tracking script is just another piece of JavaScript, I would give it a proper treatment also in terms of your website’s performance. Because the most of the setting script doesn’t change, you can remove it from the inline script block and include it (minimized) into a JavaScript bundle to:

  1. allow the browsers to cache some extra bytes of code;
  2. decrease the needed number of HTTP requests to your server.

Because we are going to use jQuery library, the only thing that you have to do is to make sure, that the library will be initialized, when we will need to use it. So I would recommend that jQuery is the first and our setting script the second script in the bundle. It might look like in this file.

First tip: Custom Events

With this functionality which is built-in the jQuery library you can easily measure activity of your website’s visitors that is purely controller by another JavaScript within a single page. You can use it for interactions with tabbed content, carousels, pagination or whatever you decided to implement in JavaScript or AJAX to enrich your visitor’s experience.

Somewhere within your JavaScript code:

// Fire Event

$(document).trigger("custom", [{

       param: "value"

}]);

The corresponding part handling the event:

// EVENT HANDLER

$(document).bind("custom", function (e, extraParameters) {

       alert(extraParameters.param);

});

The main advantage of this approach is that you can set some basic conventions for your frontend developers so they would fire a Custom Event on every measurable interaction. Then it is up to you whether you will implement the event’s handler to do the actual measurement.

Example 1: Measuring AJAX calls

You should probably measure only the successful requests, so the code might look like this:

// in the AJAX call definition

$.ajax({

       url: "myurl.html",

       success: function(){

             // ...

             $(document).trigger("ajax:call", [{

                    trackURL: $(this).url

             }]);

       }

});

And when you decide to measure this event, you can simply extend your GATC

// EVENT HANDLER

$(document).bind("ajax:call", function (e, extraParameters) {

       _gaq.push(["_trackPageview", extraParameters.trackURL]);

});

Conclusion

I hope this was somehow useful to you. I would like to continue with similar tips, so stay tuned.

Introduction

Why should we bother? Because it is actionable!

Internal search is the best place to gather feedback from your potential customers. They come to your website and tell you:

  • what they want to find there;
  • where did they gave up trying to navigate there and used search functionality instead.

But what do they do if they see an empty results page? Some might try to refine their search phrase, but I would say that it really doesn’t improve their overall experience.

It also might be the good signal for you to:

  • deliver content that is not currently present on your website;
  • change copywriting a bit in case you have picked a different words for the content;
  • or try to implement a manually added results for those searches.

Prerequisites

This article is meant to describe possible solutions when you are using a newer asynchronous Google Analytics tracking code placed in the head section of your website.

Google Analytics doesn’t provide this report by default. So we will have to do some extra work to achieve this. The first thing that is necessary to do is to be sure that you are able to identify a zero search results page programmatically.

Then you need to be able to manipulate the Google Analytics Tracking Script a bit or include an extra block of JavaScript into the tracked page.

Options to consider

You certainly don’t want to use an extra _trackPageview call, because this would inflate your data (especially Pages per Visit metric).

In certain cases you actually might be able to modify the tracked URL, but it can be achieved only in particular Web Content Management Systems that are able to pass in all the variables from the page into any template fragment of the generated page. With this capability, you could manipulate the tracked URL as described in this article by Justin Cutroni. The resulting code might look a bit like this:

<script type="text/javascript">
       var _gaq = _gaq || [],
             p = document.location.pathname,
             s = document.location.search;

       _gaq.push(['_setAccount', 'UA-15436952-1']);
<? if (resultsCount == 0) { ?>
       _gaq.push(['_trackPageview', p + s + '&category=no-results']);
<? } else {?>
       _gaq.push(['_trackPageview']);
<? } ?>
       (function() {
             ...you know this part...
       })();
</script>

Afterwards you can proceed with the Site Search functionality configuration by the instructions from Justin’s article.

If you don’t have such a comfortable CMS, you can still measure some extra data with the two following features of Google analytics.

Event Tracking

This method was already described in the article Using Google Analytics to Track ‘Zero Results Found’ for Site Searches by Bob Scavilla. I would just point out that it might be a lot easier if the actual search term would be generated by the CMS so you won’t have to suck it from the URL with a regular expression. The resulting code looks much simpler thought:

<? if (resultsCount == 0) { ?>
<script type="text/javascript">
       _gaq.push([
              '_trackEvent',
              'Search',
              'No-results',
              '<?=$searchTerm?>'
       ]);
</script>
<? } ?>

Custom Variables

The first thing you can do is to use a page-level custom variable. You can store the actual zero results search terms like this:

<? if (resultsCount == 0) { ?>
<script type="text/javascript">
       _gaq.push([
       		'_setCustomVar',
		1,
		'No-results',
		'<?=$searchTerm?>',
		3
	]);
</script>
<? } ?>

or you can store the particular results count:

<script type="text/javascript">
       _gaq.push([
       		'_setCustomVar',
		1,
		'Results-count',
		'<?=$resultsCount?>',
		3
	]);
</script>

Then if you are a little advanced, you can use the API to show all search terms and their count of results in one report (using ga:searchKeyword and ga:customVarValue1 dimensions and ga:pageviews metric).

Conclusion

The only downturn of some of these methods is that the Site Search Terms report still includes all the searches that ended up with no results and you cannot really distinguish them.

Rozhodl jsem se na svém blogu postupně uveřejňovat drobné praktické tipy, jak si zpříjemnit práci s Google Analytics. Tento tip je tedy prvním z řady a doufám, že si najdu čas i na další vydání.

Problém

Chcete-li v zobrazeném reportu porovnat čtyři pokročilé segmenty, jednoduchým způsobem toho nelze docílit. Po výběru tří segmentů se vždy jako čtvrtý automaticky doplní segment „Všechny návštěvy“.

Postup řešení

  1. Zobrazte 3 ze 4 segmentů, které vás zajímají („Všechny návštěvy se jako 4. segment doplní automaticky“);
  2. přejděte na libovolný jiný report;
  3. ve zdrojovém kódu seznamu pokročilých segmentů najděte číselné ID 4. segmentu, který vás zajímá *) **);
  4. v URL najděte parametr „seg0=-1“;
  5. -1 nahraďte číselným ID čtvrtého segmentu;
  6. následně můžete prohlížet libovolné reporty, které pokročilou segmentaci umožňují.

*) jednodušší to je např. ve Firebugu

**) toto ID můžete najít také tak, že daný segment použijete samotný, pak bude v URL po překliknutí na jiný report v parametru „seg0“

Update

Na Lupě dnes (17.2.2011) vyšel obsáhlejší návod na hackování pokročilých segmentů.

Málokdo dělá A/B nebo multi-variantní testování bez souběžného měření návštěvnosti. Tímto článkem bych chtěl shrnout, jaké potíže vás mohou potkat, pokud zvolíte nejběžnější kombinaci nástrojů od Googlu (celý článek se týká pouze multi-variantních testů, protože toto nastavení doporučuji i pro testy se dvěma variantami – důvody mohu zájemcům vysvětlit v jiném článku nebo v komentářích). Mohlo by se totiž zdát, že když oba nástroje pocházejí od stejného výrobce a využívá dokonce shodnou technologii sběru dat, bude jejich integrace bezbolestná. Omyl.

Zásadním problémem je, že vývoj obou nástrojů probíhá nezávisle. Ačkoliv Google o integraci již nějakou chvíli sám hovoří a je ze stran agentur i koncových klientů bombardován žádostmi o řešení, stále se v tomto ohledu příliš nestalo. Nějaké pokusy již na webu lze nalézt (většinou v angličtině), ale žádné z nich neuvažuje všechny případy užití a navíc zatím ještě neřeší nový asynchronní sledovací kód.

Takže co všechno vás čeká, pokud se rozhodnete na svém webu využívat Google Analytics (dále GA) a Google Website Optimizer (dále GWO) současně?

Jak zajistit, aby se to nepralo?

Na testovací stránce řešíme spuštění dvou měřících skriptů (GA a GWO). Jsou-li oba skripty nakonfigurovány podobně, přepisují si cookies s údaji o návštěvníkovi a mohou tak poškodit vaše nasbíraná data.

GWO je totiž založen na starší verzi měřicího skriptu GA z dob, kdy se ještě jmenovalo toto řešení Urchin Software. Skripty tedy používají stejnou metodu sběru dat – JavaScriptem nashromážděná data v kombinaci s identifikací návštěvníků ve stejných cookies (__utma, __utmb, __utmc, __utmz a potažmo __utmv), která jsou odesílána na servery Googlu v podobě requestu na stejný jedno-pixelový obrázek s parametry.

Kontrolní skript navíc využívá své vlastní cookies (__utmx a __utmxx), kterými zajišťuje trvalost přiřazení jedné kombinace k danému návštěvníkovi.

Asynchronní kód

Kontrolní skript GWO je nutně synchronní (musíme jej spustit ještě před začátkem vykreslování vlastní stránky, aby mohl měnit její obsah podle nastavení experimentu), proto také musí vždy být přímo v hlavičce dokumentu. K plné kontrole dvou měřících skriptů na stránce ale potřebujete, aby se skripty spustily v určeném pořadí. Toho nelze dosáhnout, kombinujeme-li nový asynchronní skript GA a starý synchronní měřicí skript, který vygeneruje nastavení experimentu v GWO.

Pokud použijeme skripty vygenerované jednotlivými nástroji a umístíme je, jak nám Google doporučuje, bude navíc stránka zbytečně vyhodnocovat dvakrát hlavní měřicí skript. To si můžete prohlédnout na prvním příkladu.

Doporučuji proto využívat i pro měření GWO experimentů asynchronní syntax, který navíc umožňuje snazší inicializaci druhého trackeru.

Nastavení domén cookies

Abychom zabránili vzájemnému přepisování cookies identifikujících návštěvníka, můžeme se pokusit cookies pro oba nástroje oddělit (každý bude mít svoje) nebo si ohlídáme pořadí skriptů a druhému zakážeme přepisovat alespoň cookie s informací o zdroji návštěvnosti (__utmz). Jinak se může stát, že nám vyhledávač přidaný v nastavení GA (v dalším příkladu jde o vyhledávač „search.cataluc.cz“) nerozpozná skript GWO, který dané nastavení nemá, a zdroj přepíše (když z předchozího odkazu přejdete na testovací stránku, nastaví nejdříve skript GA správně zdroj na vyhledávač „search.mrkef.net“, ale v zápětí jej přepíše měřicí skript GWO na vyhledávač „search“).

Já doporučuji druhou cestu. U ní je třeba zajistit zejména shodné nastavení domény a jejího hashování v hodnotách cookies. To je nutné učinit nejen pro oba měřicí skripty, ale také pro kontrolní skript GWO. Nejlépe se mi k tomu osvědčila definice globálních proměnných, které zná kontrolní skript GWO (_udn a _uhash) a jejich využití při nastavení obou trackerů – jenom pozor na to, že nastavení těchto proměnných budete muset udělat na každé stránce, nikoliv pouze na testovací.

Data o testu v Analytics

Co umí Website Optimizer?

Chcete-li vyhodnocovat experimenty pouze v GWO, jste značně omezení – měří totiž pouze konverzní poměr k jednomu definovanému cíli (Jaký podíl návštěv, který obsahoval testovanou stránku, obsahoval zároveň cílovou stránku?).

Co nás dále může zajímat?

Často ale potřebujeme data bohatší. Zajímá nás další chování návštěvníků po zhlédnutí testované stránky, vyhodnocování testu i podle dalších parametrů (Jaký je Bounce Rate testovaných variant? Má na test vliv i prohlížeč a jeho verze nebo rozlišení obrazovky?). Statisticky zdatnější experimentátoři mohou pak tato data využít také k ověření, že vyhodnocovaný konverzní poměr je statisticky nezávislý na způsobu volby skupin, kterým se obě varianty zobrazují.

Varianty integrace dat

Naším cílem je tedy dostat do GA informaci o tom, která z variant se danému návštěvníkovi zobrazila (pokud navštívil testovací stránku).

Tuto informaci můžeme zaznamenat buď do tzv. „User-defined Variable“ nebo do nových „Custom Variables“, které mají časem tuto jedinou proměnnou plně nahradit. Aktuálně má stále „User-defined Variable“ jednu podstatnou výhodu – lze podle ní filtrovat návštěvnost. Díky tomu můžete u vybraných testů vyrobit profily, které budou obsahovat pouze data o chování návštěvníků, kteří viděli některou konkrétní variantu. U „Custom Variables“ si budete muset vystačit s vyhodnocováním pomocí pokročilých segmentů, které mohou za určitých okolností zobrazovat zkreslená data (díky tzv. vzorkování).

Další nepříliš známou variantou může být ještě sledování testů prostřednictvím „Site Search“, kdy do GA místo URL adresy testované stránky zaznamenáte URL prodlouženou o dva parametry (např. test=IDTESTU a varianta=IDVARIANTY). Ale o tomto nastavení zase někdy jindy.

Shrnutí

Během psaní tohoto článku jsem narazil na spousty dalších možností a souvislostí, které se mi do jednoho postu jednoduše nevejdou. Je proto možné, že se tomuto tématu budu věnovat i nadále. Očekávám ale v budoucnosti razantnější změny ze strany Googlu a těším se, že se bez takovýchto složitostí nakonec obejdeme.

Všechny příklady, včetně finálního řešení najdete na rozcestníku, který jste již možná v rámci jednotlivých příkladů objevili.

Předem upozorňuji, že následující článek bude obsahovat pokročilejší návod. Pokud nejste webovým analytikem, raději se mu vyhněte obloukem, protože jinak skončíte s papírem, tužkou a nechápavým pohledem na tváři.

Proč tento článek píšu

Kdo zná specifika nastavení cílů a trychtýřů v Google Analytics, určitě mi dá za pravdu.

Trychtýře v Google Analytics nejsou příliš flexibilní nástroj.

Proč tomu tak je? Zejména díky nemožnosti nastavit trychtýře zpětně. Pokaždé jste odkázáni pouze na nová data počínaje dnem nastavení trychtýře. Nejednomu z nás pak také způsobil vrásky nějaký překlep nebo chybka v porovnání s regulárním výrazem, o které se díky zpoždění vyhodnocování trychtýřů až 24 hodin dozvíte příliš pozdě.

Naštěstí existuje lék v podobě analýzy dat přes Google Analytics Data Export API.

Co potřebujete k dosažení výsledku

Jelikož nechci do tohoto článku zatahovat programování, použiji k získávání dat volně dostupný Data Feed Query Explorer. Má dvě zásadní nevýhody oproti vlastní implementaci stahovače dat v některém z podporovaných jazyků.

  1. Nelze pokládat dotazy na API v cyklech.
  2. Je nutné data ručně kopírovat z vygenerované HTML tabulky.

Výhodou zase může být, že nemusíte dohledávat identifikátory profilů, ze kterých chcete data stahovat, ani názvy dimenzí a metrik, kterými definujete své dotazy.

K další vizualizaci dat pak můžete využít libovolný tabulkový procesor.

Formální definice trychtýře

V oficiální dokumentaci v uživatelském rozhraní se dočteme, že z reportu se dozvíme:

V kterém okamžiku návštěvníci, kteří určenou cestu započali, tento proces opouštějí?

Poznámky k tomuto shrnutí:

  • Záleží na přepínači povinnosti prvního kroku, zda mohou návštěvníci danou cestu započít někdy dále v trychtýři (klidně na cílové stránce).
  • Stejně jako u cílů jsou v trychtýři zahrnuti návštěvníci vždy pouze jednou (ve smyslu „kam se dostali v cestě nejdále“).

Nadále budu uvažovat pouze trychtýř bez povinnosti prvního kroku, ale na konci článku si jistě sami dokážete odvodit, jak by se dal získat trychtýř včetně tohoto přepínače.

Vstup do trychtýře

Vstupem do trychtýře tedy chápeme unikátní zobrazení stránky, které předcházelo danému kroku a nebyla to stránka kroku předchozího (zde je drobná odchylka od chápání trychtýřů v Google Analytics, jelikož moje implementace nezahrnuje do cesty návštěvníky, kteří některý z kroků „přeskočí“ – u mě se pak objeví zase ve vstupech kroku následujícího). V případě, že návštěvník započal svoji návštěvu rovnou v některé ze stránek cesty, označíme vstup jako „(entrance)“.

Výstup z trychtýře

Výstupem z trychtýře je pak unikátní zobrazení stránky, která následovala po daném kroku trychtýře u uživatelů, kteří nenavštívili další krok trychtýře.

Sekvence dotazů na API

Vlastní trychtýř tedy sestavíme vždy ze dvou dotazů pro každý definovaný krok s následujícími parametry:

Typ dotazu parametr hodnota
Vstup filters ga:nextPagePath==/aktualni-krok.html
Vstup segment dynamic::ga:pagePath!=/predchozi-krok.html
Výstup filters ga:previousPagePath==/aktualni-krok.html
Výstup segment dynamic::ga:pagePath!=/nasledujici-krok.html

Přičemž segment můžeme vynechat u vstupů do prvního kroku a výstupů z kroku posledního.

Pro všechny dotazy se pak nemění nastavení parametrů dimensions, metrics, sort, start-date, end-date, max-results (nejvíce 10 000) a ids.

parametr hodnota
dimensions ga:previousPagePath,ga:nextPagePath
metrics ga:uniquePageviews
sort -ga:uniquePageviews
start-date 2010-04-01*
end-date 2010-04-01*
max-results 10 000*
ids ID vašeho profilu*

* toto není apríl – data označená hvězdičkou si samozřejmě zvolte dle svých potřeb

Nakonec potřebujete ještě poslední dotaz, kterým získáte počty unikátních shlédnutí jednotlivých kroků trychtýře.

Následně lze také dopočítat, jaké procento návštěvníků se dostalo k následujícímu kroku (počet zobrazení následujícího kroku bez zobrazení jiných vstupních stránek dělený počtem zobrazení aktuálního kroku) a kolik lidí z trychtýře opustilo celý web (počet zobrazení daného kroku minus počet přenosů do kroku dalšího minus počet zobrazení jiných výstupních stránek).

Většina nedávno oznámených novinek v Google Analytics nabíhá do vašich účtů postupně. Jednou z těch pomalejších jsou i reporty návštěvnosti z mobilních zařízení. V některých účtech je již mám k dispozici a začínám experimentovat i se server-side měřícími kódy.

Než vám ale mobilní trackování naběhne, rád bych se podělil o pokročilý segment, který také dokáže poměrně přesně odhalit, jaký podíl vaší návštěvnosti je právě z mobilních zařízení (aktuálně pouze z těch přístrojů, které podporují JavaScript a cookies a nechají se změřit standardním trackovacím kódem).

Pokročilý segment jsem definoval na shodu následujících dimenzí podle regulárních výrazů:

DimenzeRegulární výraz

Operating System iPhone|SymbianOS|iPod|Android|Samsung|Sony|BlackBerry|LG|Nokia|Playstation Portable
Browser HTC_|SAMSUNG|Opera Mini|Playstation Portable|Nintendo DS
Screen Resolution ^176x|^220x|^240x|^320x|^360x|^400x|^480x

Jelikož na mobilních zařízeních najdeme i operační systém Windows, ale většina návštěv s tímto systémem nespadá do mobilní kategorie, je nutné Windows do tohoto pole nezařazovat a pokusit se odchytit tyto uživatele přes mobilní prohlížeče nebo menší rozlišení.

Segment samozřejmě není absolutně přesný – bylo by vhodné lépe prozkoumat možná rozlišení a navíc je nutné sledovat i aktuálně používané operační systémy a prohlížeče a segment průběžně upravovat. Na základní rychloanalýzku podílu mobilní návštěvnosti a jeho pomalého ale jistého nárůstu mi ale dostačuje.

…aneb pozor na innerHTML v Exploreru

Vzhledem k tomu, že mi tahle peripetie ukradla dnes půl hodiny života, rozhodl jsem se, že ji zveřejním, třeba existuje někdo, kdo o ní neví a pomůžu mu.

Kapitola první – Microsoft je zase chytřejší než konkurence…

…a přesně ví, kam který element patří.

Proto vás nenechá poměrně oblíbenou JavaScriptovou funkcí innerHTML vložit některé věci, které nevyhovují standardům (nebo Exploreru?).

Příklad

Nelze vložit <form> do jiného <form>u. Obdobně to funguje například při vkládání blokových objektů do paragraphu atd.

Kapitola druhá – chybové hlášky, jak jsme na ně zvyklí

Kámen úrazu je ovšem to, jak se tato nevole prohlížečů z dílny výše zmíněného výrobce „vkládat něco někam“ projeví. Exception, která je v tuto chvíli vyhozena zní „Neznámá chyba při běhu programu“ („Unknown runtime error“) a pakliže neošetřujete většinu svého kódu konstrukcí try {} catch (error) {}, nedozvíte se ani to. Pak si zkuste něco ladit.

Vlastnosti: ,