diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results.hbs b/app/assets/javascripts/discourse/app/components/search-menu/results.hbs
index a026fd5322f..bfbf0911971 100644
--- a/app/assets/javascripts/discourse/app/components/search-menu/results.hbs
+++ b/app/assets/javascripts/discourse/app/components/search-menu/results.hbs
@@ -43,6 +43,7 @@
             @resultTypes={{this.resultTypesWithComponent}}
             @topicResultsOnly={{true}}
             @closeSearchMenu={{@closeSearchMenu}}
+            @searchLogId={{this.searchLogId}}
           />
           <SearchMenu::Results::MoreLink
             @updateTypeFilter={{@updateTypeFilter}}
@@ -63,6 +64,7 @@
             @closeSearchMenu={{@closeSearchMenu}}
             @searchTermChanged={{@searchTermChanged}}
             @displayNameWithUser={{true}}
+            @searchLogId={{this.searchLogId}}
           />
         {{/if}}
       {{/if}}
diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results.js b/app/assets/javascripts/discourse/app/components/search-menu/results.js
index 3be639b32b4..4c8be480c06 100644
--- a/app/assets/javascripts/discourse/app/components/search-menu/results.js
+++ b/app/assets/javascripts/discourse/app/components/search-menu/results.js
@@ -46,6 +46,10 @@ export default class Results extends Component {
     return content;
   }
 
+  get searchLogId() {
+    return this.search.results.grouped_search_result?.search_log_id;
+  }
+
   @action
   updateSearchTopics(value) {
     this.searchTopics = value;
diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs b/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs
index 2c9660a994b..11cf81ebb71 100644
--- a/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs
+++ b/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs
@@ -11,10 +11,19 @@
       {{#each resultType.results as |result|}}
         {{! template-lint-disable no-pointer-down-event-binding }}
         {{! template-lint-disable no-invalid-interactive }}
-        <li class="item" {{on "keydown" this.onKeydown}}>
+        <li
+          class="item"
+          {{on
+            "keydown"
+            (fn this.onKeydown (hash resultType=resultType result=result))
+          }}
+        >
           <a
             href={{or result.url result.path}}
-            {{on "click" this.onClick}}
+            {{on
+              "click"
+              (fn this.onClick (hash resultType=resultType result=result))
+            }}
             class="search-link"
           >
             <resultType.component
diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results/types.js b/app/assets/javascripts/discourse/app/components/search-menu/results/types.js
index 82a52cf4589..1f4edc87f59 100644
--- a/app/assets/javascripts/discourse/app/components/search-menu/results/types.js
+++ b/app/assets/javascripts/discourse/app/components/search-menu/results/types.js
@@ -2,6 +2,7 @@ import Component from "@glimmer/component";
 import { action } from "@ember/object";
 import { service } from "@ember/service";
 import { wantsNewWindow } from "discourse/lib/intercept-click";
+import { logSearchLinkClick } from "discourse/lib/search";
 import DiscourseURL from "discourse/lib/url";
 
 export default class Types extends Component {
@@ -22,7 +23,13 @@ export default class Types extends Component {
   }
 
   @action
-  onClick(event) {
+  onClick({ resultType, result }, event) {
+    logSearchLinkClick({
+      searchLogId: this.args.searchLogId,
+      searchResultId: result.id,
+      searchResultType: resultType.type,
+    });
+
     if (wantsNewWindow(event)) {
       return;
     }
@@ -32,7 +39,7 @@ export default class Types extends Component {
   }
 
   @action
-  onKeydown(event) {
+  onKeydown({ resultType, result }, event) {
     if (event.key === "Escape") {
       this.args.closeSearchMenu();
       event.preventDefault();
@@ -40,6 +47,11 @@ export default class Types extends Component {
     } else if (event.key === "Enter") {
       event.preventDefault();
       event.stopPropagation();
+      logSearchLinkClick({
+        searchLogId: this.args.searchLogId,
+        searchResultId: result.id,
+        searchResultType: resultType.type,
+      });
       this.routeToSearchResult(event.target.href);
       return false;
     }
diff --git a/app/assets/javascripts/discourse/app/widgets/header.js b/app/assets/javascripts/discourse/app/widgets/header.js
index 0e688122554..b83f3ae1974 100644
--- a/app/assets/javascripts/discourse/app/widgets/header.js
+++ b/app/assets/javascripts/discourse/app/widgets/header.js
@@ -7,7 +7,6 @@ import { headerIconsDAG } from "discourse/components/header/icons";
 import { addExtraUserClasses } from "discourse/helpers/user-avatar";
 import { wantsNewWindow } from "discourse/lib/intercept-click";
 import scrollLock from "discourse/lib/scroll-lock";
-import { logSearchLinkClick } from "discourse/lib/search";
 import { isDocumentRTL } from "discourse/lib/text-direction";
 import DiscourseURL from "discourse/lib/url";
 import { scrollTop } from "discourse/mixins/scroll-top";
@@ -602,24 +601,6 @@ export default createWidget("header", {
     this.toggleBodyScrolling(false);
   },
 
-  linkClickedEvent(attrs) {
-    let searchContextEnabled = false;
-    if (attrs) {
-      searchContextEnabled = attrs.searchContextEnabled;
-
-      const { searchLogId, searchResultId, searchResultType } = attrs;
-      if (searchLogId && searchResultId && searchResultType) {
-        logSearchLinkClick({ searchLogId, searchResultId, searchResultType });
-      }
-    }
-
-    if (!searchContextEnabled) {
-      this.closeAll();
-    }
-
-    this.updateHighlight();
-  },
-
   toggleSearchMenu() {
     if (this.site.mobileView) {
       const context = this.search.searchContext;
diff --git a/app/assets/javascripts/discourse/tests/acceptance/search-test.js b/app/assets/javascripts/discourse/tests/acceptance/search-test.js
index 6ed421bb43e..b53025ab4a1 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/search-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/search-test.js
@@ -496,6 +496,10 @@ acceptance("Search - Authenticated", function (needs) {
     server.get("/t/2179.json", () => {
       return helper.response({});
     });
+
+    server.post("/search/click", () => {
+      return helper.response({ success: "OK" });
+    });
   });
 
   test("full page search - the right filters are shown", async function (assert) {
@@ -1140,6 +1144,10 @@ acceptance("Search - assistant", function (needs) {
         ],
       });
     });
+
+    server.post("/search/click", () => {
+      return helper.response({ success: "OK" });
+    });
   });
 
   test("initial options - shows category shortcuts when typing #", async function (assert) {
diff --git a/spec/system/search_spec.rb b/spec/system/search_spec.rb
index 623ba33da70..fdd932cc09d 100644
--- a/spec/system/search_spec.rb
+++ b/spec/system/search_spec.rb
@@ -106,5 +106,25 @@ describe "Search", type: :system do
       search_page.click_search_icon
       expect(search_page).to have_topic_title_for_first_search_result(topic.title)
     end
+
+    it "tracks search result clicks" do
+      expect(SearchLog.count).to eq(0)
+
+      visit("/")
+      search_page.click_search_icon
+      search_page.type_in_search_menu("test")
+      search_page.click_search_menu_link
+
+      expect(search_page).to have_topic_title_for_first_search_result(topic.title)
+      find(".search-menu-container .search-result-topic", text: topic.title).click
+
+      try_until_success { expect(SearchLog.count).to eq(1) }
+      try_until_success { expect(SearchLog.last.search_result_id).not_to eq(nil) }
+
+      log = SearchLog.last
+      expect(log.term).to eq("test")
+      expect(log.search_result_id).to eq(topic.first_post.id)
+      expect(log.search_type).to eq(SearchLog.search_types[:header])
+    end
   end
 end