Skip to content

Commit 4d0d4e5

Browse files
committed
Fix current page detection for clean URLs
Previously, the sidebar JavaScript logic for detecting the "active" page relied on URL and assumed it would end with .html. When using clean URLs without this suffix, this logic would fail to correctly highlight the current page in the sidebar. This change moves the current page identification to server-side rendering by adding a data-current-link attribute to the HTML root element. Fixes #2962
1 parent 7b29f8a commit 4d0d4e5

3 files changed

Lines changed: 10 additions & 8 deletions

File tree

crates/mdbook-html/front-end/templates/index.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!DOCTYPE HTML>
2-
<html lang="{{ language }}" class="{{ default_theme }} sidebar-visible" dir="{{ text_direction }}">
2+
<html lang="{{ language }}" class="{{ default_theme }} sidebar-visible" dir="{{ text_direction }}" data-current-link="{{ current_link }}">
33
<head>
44
<!-- Book generated using mdBook -->
55
<meta charset="UTF-8">

crates/mdbook-html/front-end/templates/toc.js.hbs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ class MDBookSidebarScrollbox extends HTMLElement {
1010
connectedCallback() {
1111
this.innerHTML = '{{#toc}}{{/toc}}';
1212
// Set the current, active page, and reveal it if it's hidden
13-
let current_page = document.location.href.toString().split('#')[0].split('?')[0];
14-
if (current_page.endsWith('/')) {
15-
current_page += 'index.html';
16-
}
13+
const current_link = document.documentElement.dataset.currentLink;
1714
const links = Array.prototype.slice.call(this.querySelectorAll('a'));
1815
const l = links.length;
1916
for (let i = 0; i < l; ++i) {
@@ -23,10 +20,9 @@ class MDBookSidebarScrollbox extends HTMLElement {
2320
link.href = path_to_root + href;
2421
}
2522
// The 'index' page is supposed to alias the first chapter in the book.
26-
if (link.href === current_page
23+
if (href === current_link
2724
|| i === 0
28-
&& path_to_root === ''
29-
&& current_page.endsWith('/index.html')) {
25+
&& current_link === 'index.html') {
3026
link.classList.add('active');
3127
let parent = link.parentElement;
3228
while (parent) {

crates/mdbook-html/src/html_handlebars/hbs_renderer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ impl HtmlHandlebars {
8585
ctx.data.insert("title".to_owned(), json!(title));
8686
ctx.data
8787
.insert("path_to_root".to_owned(), json!(fs::path_to_root(path)));
88+
let current_link = path.with_extension("html").to_url_path();
89+
ctx.data
90+
.insert("current_link".to_owned(), json!(current_link));
8891
if let Some(ref section) = ch.number {
8992
ctx.data
9093
.insert("section".to_owned(), json!(section.to_string()));
@@ -127,6 +130,8 @@ impl HtmlHandlebars {
127130
ctx.data.insert("path".to_owned(), json!("index.md"));
128131
ctx.data.insert("path_to_root".to_owned(), json!(""));
129132
ctx.data.insert("is_index".to_owned(), json!(true));
133+
ctx.data
134+
.insert("current_link".to_owned(), json!("index.html"));
130135
let rendered_index = ctx.handlebars.render("index", &ctx.data)?;
131136
debug!("Creating index.html from {}", ctx_path);
132137
fs::write(ctx.destination.join("index.html"), rendered_index)?;
@@ -180,6 +185,7 @@ impl HtmlHandlebars {
180185
// Set a dummy path to ensure other paths (e.g. in the TOC) are generated correctly
181186
data_404.insert("path".to_owned(), json!("404.md"));
182187
data_404.insert("content".to_owned(), json!(html_content_404));
188+
data_404.insert("current_link".to_owned(), json!("404.html"));
183189

184190
let mut title = String::from("Page not found");
185191
if let Some(book_title) = &ctx.config.book.title {

0 commit comments

Comments
 (0)