Skip to content

Commit

Permalink
FIX: Do not track first AJAX request as a pageview (#22661)
Browse files Browse the repository at this point in the history
When the app boots, Ember fires a `routeWillChange` event. This was causing us to set the `_trackView` flag in our ajax library, which would cause the next request to have the `Discourse-Track-View` header, despite not being relevant to the page view. Depending on the plugins/themes installed, this could lead to 'double counting' of pageviews. (because the initial HTML request is also counted as a page view)

This commit updates the the logic to ignore the first transition (by checking `transition.from`), and also introduces an acceptance test for the behaviour.

Co-authored-by: Régis Hanol <regis@hanol.fr>
  • Loading branch information
davidtaylorhq and ZogStriP committed Jul 18, 2023
1 parent f76a9aa commit 104baab
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
Expand Up @@ -3,15 +3,15 @@ import {
resetPageTracking,
startPageTracking,
} from "discourse/lib/page-tracker";
import { viewTrackingRequired } from "discourse/lib/ajax";
import { resetAjax, trackNextAjaxAsPageview } from "discourse/lib/ajax";

export default {
after: "inject-objects",

initialize(owner) {
// Tell our AJAX system to track a page transition
const router = owner.lookup("router:main");
router.on("routeWillChange", viewTrackingRequired);
router.on("routeWillChange", this.handleRouteWillChange);

let appEvents = owner.lookup("service:app-events");
let documentTitle = owner.lookup("service:document-title");
Expand Down Expand Up @@ -64,7 +64,15 @@ export default {
}
},

handleRouteWillChange(transition) {
// will be null on initial boot transition, which is already tracked as a pageview via the HTML request
if (transition.from) {
trackNextAjaxAsPageview();
}
},

teardown() {
resetPageTracking();
resetAjax();
},
};
6 changes: 5 additions & 1 deletion app/assets/javascripts/discourse/app/lib/ajax.js
Expand Up @@ -15,10 +15,14 @@ export function setTransientHeader(key, value) {
_transientHeader = { key, value };
}

export function viewTrackingRequired() {
export function trackNextAjaxAsPageview() {
_trackView = true;
}

export function resetAjax() {
_trackView = false;
}

export function setLogoffCallback(cb) {
_logoffCallback = cb;
}
Expand Down
@@ -0,0 +1,39 @@
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import { click, visit } from "@ember/test-helpers";
import { test } from "qunit";
import pretender from "discourse/tests/helpers/create-pretender";

acceptance("Page tracking", function () {
test("sets the discourse-track-view header correctly", async function (assert) {
const trackViewHeaderName = "Discourse-Track-View";
assert.strictEqual(
pretender.handledRequests.length,
0,
"no requests logged before app boot"
);

await visit("/");
assert.strictEqual(
pretender.handledRequests.length,
1,
"one request logged during app boot"
);
assert.strictEqual(
pretender.handledRequests[0].requestHeaders[trackViewHeaderName],
undefined,
"does not track view for ajax before a transition has taken place"
);

await click("#site-logo");
assert.strictEqual(
pretender.handledRequests.length,
2,
"second request logged during next transition"
);
assert.strictEqual(
pretender.handledRequests[1].requestHeaders[trackViewHeaderName],
"true",
"sends track-view header for subsequent requests"
);
});
});

0 comments on commit 104baab

Please sign in to comment.