Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions sidebar-scroll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
(function () {
if (typeof window === "undefined") return;

// Mintlify's markup is not a stable contract; take the first scrollable match.
function findSidebar() {
var candidates = document.querySelectorAll(
"aside, nav[aria-label='Sidebar'], aside[aria-label='Sidebar'], #sidebar"
);
for (var i = 0; i < candidates.length; i++) {
if (candidates[i].scrollHeight > candidates[i].clientHeight + 1) {
return candidates[i];
}
}
return null;
}

function showActive() {
var sb = findSidebar();
if (!sb) return;
var link = sb.querySelector(
"a[aria-current='page'], a[aria-current='true'], a[data-active='true']"
);
// Guard against acting on the previous page's link before the DOM updates.
if (!link || link.pathname !== location.pathname) return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No retry after race condition guard causes silent failure

Medium Severity

On SPA navigation, data-current-path on <html> triggers the MutationObserver, which schedules a single requestAnimationFrame(showActive). If Mintlify's React render cycle hasn't yet updated aria-current on sidebar links by the time that frame fires, the guard on line 24 (link.pathname !== location.pathname) correctly bails out to avoid acting on the old link — but there is no retry. The feature silently becomes a no-op for that navigation. The PR description mentions "polling until the sidebar mounts plus one 150ms re-apply" but neither mechanism is actually implemented.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e2ef311. Configure here.


var sbRect = sb.getBoundingClientRect();
var linkRect = link.getBoundingClientRect();
var margin = 24;

if (linkRect.top < sbRect.top + margin) {
sb.scrollTop -= sbRect.top + margin - linkRect.top;
} else if (linkRect.bottom > sbRect.bottom - margin) {
sb.scrollTop += linkRect.bottom - (sbRect.bottom - margin);
}
}

// Mintlify has no navigation event, but it rewrites data-current-path on
// <html> on every client-side route change. That mutation is our signal.
var html = document.documentElement;
var last = html.getAttribute("data-current-path");
new MutationObserver(function () {
var cur = html.getAttribute("data-current-path");
if (cur === last) return;
last = cur;
requestAnimationFrame(showActive);
}).observe(html, { attributes: true, attributeFilter: ["data-current-path"] });

if (document.readyState === "complete") showActive();
else window.addEventListener("load", showActive);
})();
Loading