FEATURE: Use Beacon API for tracking clicks. (#7483)

FEATURE: Use Beacon API for tracking clicks. (#7483)

diff --git a/app/assets/javascripts/discourse/lib/ajax.js.es6 b/app/assets/javascripts/discourse/lib/ajax.js.es6
index 3420777..e2f28ce 100644
--- a/app/assets/javascripts/discourse/lib/ajax.js.es6
+++ b/app/assets/javascripts/discourse/lib/ajax.js.es6
@@ -153,6 +153,7 @@ export function ajax() {
   if (
     args.type &&
     args.type.toUpperCase() !== "GET" &&
+    url !== "/clicks/track" &&
     !Discourse.Session.currentProp("csrfToken")
   ) {
     promise = new Ember.RSVP.Promise((resolve, reject) => {
diff --git a/app/assets/javascripts/discourse/lib/click-track.js.es6 b/app/assets/javascripts/discourse/lib/click-track.js.es6
index 6fcbfcb..dae52b7 100644
--- a/app/assets/javascripts/discourse/lib/click-track.js.es6
+++ b/app/assets/javascripts/discourse/lib/click-track.js.es6
@@ -91,15 +91,25 @@ export default {
       }
     }
 
-    const trackPromise = tracking
-      ? ajax("/clicks/track", {
+    let trackPromise = Ember.RSVP.resolve();
+    if (tracking) {
+      if (navigator.sendBeacon) {
+        const data = new FormData();
+        data.append("url", href);
+        data.append("post_id", postId);
+        data.append("topic_id", topicId);
+        navigator.sendBeacon("/clicks/track", data);
+      } else {
+        trackPromise = ajax("/clicks/track", {
+          type: "POST",
           data: {
             url: href,
             post_id: postId,
             topic_id: topicId
           }
-        })
-      : Ember.RSVP.resolve();
+        });
+      }
+    }
 
     const isInternal = DiscourseURL.isInternal(href);
     const openExternalInNewTab = Discourse.User.currentProp(
diff --git a/app/controllers/clicks_controller.rb b/app/controllers/clicks_controller.rb
index 81b068c..c34c143 100644
--- a/app/controllers/clicks_controller.rb
+++ b/app/controllers/clicks_controller.rb
@@ -1,5 +1,5 @@
 class ClicksController < ApplicationController
-  skip_before_action :check_xhr, :preload_json
+  skip_before_action :check_xhr, :preload_json, :verify_authenticity_token
 
   def track
     params.require([:url, :post_id, :topic_id])
diff --git a/config/routes.rb b/config/routes.rb
index 33cb6ea..32cc4ef 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -582,7 +582,7 @@ Discourse::Application.routes.draw do
 
   resources :clicks do
     collection do
-      get "track"
+      post "track"
     end
   end
 
diff --git a/spec/requests/clicks_controller_spec.rb b/spec/requests/clicks_controller_spec.rb
index ba21bff..208be2e 100644
--- a/spec/requests/clicks_controller_spec.rb
+++ b/spec/requests/clicks_controller_spec.rb
@@ -13,7 +13,7 @@ describe ClicksController do
       sign_in(Fabricate(:user))
 
       expect {
-        get "/clicks/track", params: { url: url, post_id: post.id, topic_id: post.topic_id }, headers: headers
+        post "/clicks/track", params: { url: url, post_id: post.id, topic_id: post.topic_id }, headers: headers
       }.to change { TopicLinkClick.count }.by(1)
     end
   end

GitHub sha: 4ff11955

2 Likes