diff --git a/app/assets/javascripts/discourse/app/components/category-list-item.js b/app/assets/javascripts/discourse/app/components/category-list-item.js
index 468ce928c75..12e41368404 100644
--- a/app/assets/javascripts/discourse/app/components/category-list-item.js
+++ b/app/assets/javascripts/discourse/app/components/category-list-item.js
@@ -26,4 +26,14 @@ export default Component.extend({
       (!isMutedCategory && listType === LIST_TYPE.MUTED)
     );
   },
+
+  @discourseComputed("topicTrackingState.messageCount")
+  unreadTopicsCount() {
+    return this.category.unreadTopicsCount;
+  },
+
+  @discourseComputed("topicTrackingState.messageCount")
+  newTopicsCount() {
+    return this.category.newTopicsCount;
+  },
 });
diff --git a/app/assets/javascripts/discourse/app/components/category-unread.hbs b/app/assets/javascripts/discourse/app/components/category-unread.hbs
index 0021e01260f..459ccc57945 100644
--- a/app/assets/javascripts/discourse/app/components/category-unread.hbs
+++ b/app/assets/javascripts/discourse/app/components/category-unread.hbs
@@ -1,20 +1,17 @@
-{{#if this.category.unreadTopics}}
+{{#if this.unreadTopicsCount}}
   <a
     href={{this.category.unreadUrl}}
-    title={{i18n "topic.unread_topics" count=this.category.unreadTopics}}
+    title={{i18n "topic.unread_topics" count=this.unreadTopicsCount}}
     class="badge new-posts badge-notification"
   >{{i18n
       "filters.unread.lower_title_with_count"
-      count=this.category.unreadTopics
+      count=this.unreadTopicsCount
     }}</a>
 {{/if}}
-{{#if this.category.newTopics}}
+{{#if this.newTopicsCount}}
   <a
     href={{this.category.newUrl}}
-    title={{i18n "topic.new_topics" count=this.category.newTopics}}
+    title={{i18n "topic.new_topics" count=this.newTopicsCount}}
     class="badge new-posts badge-notification"
-  >{{i18n
-      "filters.new.lower_title_with_count"
-      count=this.category.newTopics
-    }}</a>
+  >{{i18n "filters.new.lower_title_with_count" count=this.newTopicsCount}}</a>
 {{/if}}
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/parent-category-row.hbs b/app/assets/javascripts/discourse/app/components/parent-category-row.hbs
index 8b521eef36f..151bf4d8f91 100644
--- a/app/assets/javascripts/discourse/app/components/parent-category-row.hbs
+++ b/app/assets/javascripts/discourse/app/components/parent-category-row.hbs
@@ -67,6 +67,8 @@
         @category={{this.category}}
         @tagName="div"
         @class="unread-new"
+        @unreadTopicsCount={{this.unreadTopicsCount}}
+        @newTopicsCount={{this.newTopicsCount}}
       />
     </td>
 
diff --git a/app/assets/javascripts/discourse/app/components/sub-category-item.hbs b/app/assets/javascripts/discourse/app/components/sub-category-item.hbs
index a8d88651f1a..dadf3b9801d 100644
--- a/app/assets/javascripts/discourse/app/components/sub-category-item.hbs
+++ b/app/assets/javascripts/discourse/app/components/sub-category-item.hbs
@@ -3,7 +3,11 @@
     <CategoryTitleBefore @category={{this.category}} />
     {{category-link this.category hideParent="true"}}
     {{#unless this.hideUnread}}
-      <CategoryUnread @category={{this.category}} />
+      <CategoryUnread
+        @category={{this.category}}
+        @unreadTopicsCount={{this.unreadTopicsCount}}
+        @newTopicsCount={{this.newTopicsCount}}
+      />
     {{/unless}}
   </span>
 {{/unless}}
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/models/category.js b/app/assets/javascripts/discourse/app/models/category.js
index 5101056328d..8bb0f762d92 100644
--- a/app/assets/javascripts/discourse/app/models/category.js
+++ b/app/assets/javascripts/discourse/app/models/category.js
@@ -198,6 +198,14 @@ const Category = RestModel.extend({
     return notificationLevel >= NotificationLevels.TRACKING;
   },
 
+  get unreadTopicsCount() {
+    return this.topicTrackingState.countUnread({ categoryId: this.id });
+  },
+
+  get newTopicsCount() {
+    return this.topicTrackingState.countNew({ categoryId: this.id });
+  },
+
   save() {
     const id = this.id;
     const url = id ? `/categories/${id}` : "/categories";
@@ -310,16 +318,6 @@ const Category = RestModel.extend({
     }
   },
 
-  @discourseComputed("id", "topicTrackingState.messageCount")
-  unreadTopics(id) {
-    return this.topicTrackingState.countUnread({ categoryId: id });
-  },
-
-  @discourseComputed("id", "topicTrackingState.messageCount")
-  newTopics(id) {
-    return this.topicTrackingState.countNew({ categoryId: id });
-  },
-
   setNotification(notification_level) {
     User.currentProp(
       "muted_category_ids",
diff --git a/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js b/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js
index 8ef945c88b2..c48bbfb8e97 100644
--- a/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js
+++ b/app/assets/javascripts/discourse/app/widgets/hamburger-categories.js
@@ -19,8 +19,8 @@ createWidget("hamburger-category", {
       this.attach("category-link", { category: c, allowUncategorized: true }),
     ];
 
-    const unreadTotal =
-      parseInt(c.get("unreadTopics"), 10) + parseInt(c.get("newTopics"), 10);
+    const unreadTotal = c.unreadTopicsCount + c.newTopicsCount;
+
     if (unreadTotal) {
       results.push(
         h(
diff --git a/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js b/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js
index b6ba869b6c8..67b3b9e7a93 100644
--- a/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js
+++ b/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js
@@ -198,12 +198,12 @@ export default createWidget("hamburger-menu", {
         .filter((c) => c.notification_level !== NotificationLevels.MUTED);
 
       categories = allCategories
-        .filter((c) => c.get("newTopics") > 0 || c.get("unreadTopics") > 0)
+        .filter((c) => c.newTopicsCount > 0 || c.unreadTopicsCount > 0)
         .sort((a, b) => {
           return (
-            b.get("newTopics") +
-            b.get("unreadTopics") -
-            (a.get("newTopics") + a.get("unreadTopics"))
+            b.newTopicsCount +
+            b.unreadTopicsCount -
+            (a.unreadTopicsCount + a.newTopicsCount)
           );
         });
 
diff --git a/spec/system/category_topics_spec.rb b/spec/system/category_topics_spec.rb
new file mode 100644
index 00000000000..1544ac27cdc
--- /dev/null
+++ b/spec/system/category_topics_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+describe "Viewing top topics on categories page", type: :system, js: true do
+  fab!(:user) { Fabricate(:user) }
+  let(:category_list) { PageObjects::Components::CategoryList.new }
+  fab!(:category) { Fabricate(:category) }
+  fab!(:topic) { Fabricate(:topic, category: category) }
+
+  it "displays and updates new counter" do
+    sign_in(user)
+
+    visit("/categories")
+
+    category_list.click_new_posts_badge(count: 1)
+    category_list.click_topic(topic)
+    category_list.click_logo
+    category_list.click_category_navigation
+
+    expect(category_list).to have_category(category)
+    expect(category_list).to have_no_new_posts_badge
+  end
+end
diff --git a/spec/system/page_objects/components/category_list.rb b/spec/system/page_objects/components/category_list.rb
new file mode 100644
index 00000000000..49e000bf7d7
--- /dev/null
+++ b/spec/system/page_objects/components/category_list.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module PageObjects
+  module Components
+    class CategoryList < PageObjects::Components::Base
+      def has_category?(category)
+        page.has_css?("tr[data-category-id='#{category.id}']")
+      end
+
+      def has_topic?(topic)
+        page.has_css?(topic_list_item_class(topic))
+      end
+
+      def has_no_new_posts_badge?
+        page.has_no_css?(".new-posts")
+      end
+
+      def click_category_navigation
+        page.find(".nav-pills .categories").click
+      end
+
+      def click_logo
+        page.find(".title a").click
+      end
+
+      def click_new_posts_badge(count: 1)
+        page.find(".new-posts", text: "#{count} new").click
+      end
+
+      def click_topic(topic)
+        page.find("a", text: topic.title).click
+      end
+    end
+  end
+end