Skip to content

Commit 0adfac3

Browse files
committed
Add Google Analytics events for search pages and search selections (#7157)
Address #6803
1 parent 79d96b6 commit 0adfac3

3 files changed

Lines changed: 45 additions & 5 deletions

File tree

src/NuGetGallery/Scripts/gallery/common.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,12 @@
402402
});
403403
};
404404

405+
nuget.sendAnalyticsEvent = function (category, action, label, eventValue, options) {
406+
if (window.nuget.isGaAvailable()) {
407+
ga('send', 'event', category, action, label, eventValue, options);
408+
}
409+
}
410+
405411
window.nuget = nuget;
406412

407413
jQuery.extend(jQuery.expr[':'], {
@@ -445,12 +451,13 @@
445451
$(this).click(function (e) {
446452
var href = $(this).attr('href');
447453
var category = $(this).data().track;
454+
var trackValue = $(this).data().trackValue;
448455
if (window.nuget.isGaAvailable() && href && category) {
449456
if (e.altKey || e.ctrlKey || e.metaKey) {
450-
ga('send', 'event', category, 'click', href);
457+
window.nuget.sendAnalyticsEvent(category, 'click', href, trackValue);
451458
} else {
452459
e.preventDefault();
453-
ga('send', 'event', category, 'click', href, {
460+
window.nuget.sendAnalyticsEvent(category, 'click', href, trackValue, {
454461
'transport': 'beacon',
455462
'hitCallback': window.nuget.createFunctionWithTimeout(function () {
456463
document.location = href;

src/NuGetGallery/Views/Shared/ListPackages.cshtml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,13 @@
6161
}
6262

6363
<div class="list-packages" role="list">
64+
@{ var itemIndex = Model.PageIndex * Model.PageSize; }
6465
@foreach (var package in Model.Items)
6566
{
66-
@Html.Partial("_ListPackage", package)
67+
// Only set an item index when there is a search query, for now.
68+
var thisItemIndex = string.IsNullOrWhiteSpace(Model.SearchTerm) ? null : (int?) itemIndex;
69+
@Html.Partial("_ListPackage", package, new ViewDataDictionary { { "itemIndex", thisItemIndex } })
70+
itemIndex++;
6771
}
6872
</div>
6973

@@ -76,6 +80,17 @@
7680

7781
@section bottomScripts {
7882
<script type="text/javascript">
83+
84+
@if (!string.IsNullOrWhiteSpace(Model.SearchTerm) && (Model.PageIndex == 0 || Model.Items.Count() > 0))
85+
{
86+
var action = Model.IncludePrerelease ? "search-prerel" : "search-stable";
87+
// Emit an event representing the search page and the page index. This make it easier for the search selection
88+
// event to be correlated in Google Analytics.
89+
<text>
90+
window.nuget.sendAnalyticsEvent('search-page', '@action', @Html.Raw(Json.Encode(Model.SearchTerm)), @Model.PageIndex);
91+
</text>
92+
}
93+
7994
$(function () {
8095
$("#include-prerelease").on('change', function () {
8196
var parameters = {};
@@ -99,4 +114,4 @@
99114
})
100115
});
101116
</script>
102-
}
117+
}

src/NuGetGallery/Views/Shared/_ListPackage.cshtml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
@model ListPackageItemViewModel
2+
@{
3+
// This view data will sometimes be null or missing. For example, the profile page uses this partial and should not
4+
// emit search selection events.
5+
int? itemIndex = null;
6+
int parsedItemIndex;
7+
if (ViewData.ContainsKey("itemIndex")
8+
&& int.TryParse(ViewData["itemIndex"].ToStringOrNull(), out parsedItemIndex))
9+
{
10+
itemIndex = parsedItemIndex;
11+
}
12+
}
13+
214

315
<article class="package" role="listitem">
416

@@ -10,7 +22,13 @@
1022
</div>
1123
<div class="col-sm-11">
1224
<div class="package-header">
13-
<a class="package-title" href="@Url.Package(Model.Id, Model.UseVersion ? Model.Version : null)">@Html.BreakWord(Model.Id)</a>
25+
<a class="package-title"
26+
href="@Url.Package(Model.Id, Model.UseVersion ? Model.Version : null)"
27+
@if (itemIndex.HasValue)
28+
{
29+
@:data-track="search-selection" data-track-value="@itemIndex"
30+
}
31+
>@Html.BreakWord(Model.Id)</a>
1432

1533
@if (Model.IsVerified.HasValue && Model.IsVerified.Value)
1634
{

0 commit comments

Comments
 (0)