I have:
Bug description
quarto-nav.js rewrites every link on page load to clean up index.html URLs, stashing the original in data-original-href:
links[i].dataset.originalHref = links[i].href;
links[i].href = links[i].href.replace(/\/index\.html/, "/");
The regex is unanchored, so on a site's index page the "Other Formats" link to index.html.md (the markdown twin generated when a site pairs a markdown format with html, e.g. for llms.txt workflows) is rewritten from https://example.com/index.html.md to https://example.com/.md, which 404s. Only the index page is affected, since no other page has index.html as a filename prefix; the same CommonMark link works everywhere else on the site. The served HTML is correct; only the client-side rewrite breaks it.
Still present in main today, in src/resources/projects/website/navigation/quarto-nav.js.
The index.html.md naming comes from output-file: index.html in the page metadata (tools like nbdev set this on every page of the sites they generate).
Steps to reproduce
Primary evidence is the live example under "Actual behavior" plus the code above; a minimal project for reproducing:
_quarto.yml:
project:
type: website
format:
html: default
commonmark: default
index.qmd (the output-file line gives the alternate format the index.html.md name that triggers the bug):
---
title: Home
output-file: index.html
---
Hello.
Then:
quarto render
python3 -m http.server -d _site # the rewrite is skipped on file:, so serve over http
Open the served index page and inspect the CommonMark link under "Other Formats". Note: on 1.8.25 I could confirm the rendered HTML gets the index.html.md link, but not the client-side rewrite itself, because that version routes site_libs and the .md twin outside _site when output-file is set, so the served page loads no JS; the rewrite is confirmed on the 1.9.38-built live site below.
Actual behavior
On the live example, the link's href in the DOM is rewritten to /.md and 404s; data-original-href holds the correct index.html.md: the CommonMark link on https://fastcore.fast.ai/ (generator quarto-1.9.38) points to https://fastcore.fast.ai/.md, while the same link works on every non-index page, e.g. https://fastcore.fast.ai/tour.html.
Expected behavior
The link keeps pointing at index.html.md. The clean-URL rewrite should only strip index.html at the end of the path, while still allowing a query or fragment:
links[i].href = links[i].href.replace(/\/index\.html(?=[?#]|$)/, "/");
Your environment
- No IDE involved: static rendered site viewed in a browser (observed in Chrome and Safari)
- OS: macOS 26.2
- Live example built with Quarto 1.9.38 on GitHub Actions; the unanchored regex is also in current
main and in the quarto-nav.js shipped with 1.8.25
Quarto check output
Quarto 1.8.25
[✓] Checking environment information...
Quarto cache location: /Users/jhoward/Library/Caches/quarto
[✓] Checking versions of quarto binary dependencies...
Pandoc version 3.6.3: OK
Dart Sass version 1.87.0: OK
Deno version 2.3.1: OK
Typst version 0.13.0: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
Version: 1.8.25
Path: /Applications/quarto/bin
[✓] Checking tools....................OK
TinyTeX: (not installed)
Chromium: (not installed)
[✓] Checking LaTeX....................OK
Tex: (not detected)
[✓] Checking Chrome Headless....................OK
Using: Chrome found on system
[✓] Checking basic markdown render....OK
[✓] Checking Python 3 installation....OK
Version: 3.13.2
Jupyter: 5.9.1
[✓] Checking Jupyter engine render....OK
[✓] Checking R installation...........(None)
I have:
Bug description
quarto-nav.jsrewrites every link on page load to clean upindex.htmlURLs, stashing the original indata-original-href:The regex is unanchored, so on a site's index page the "Other Formats" link to
index.html.md(the markdown twin generated when a site pairs a markdown format with html, e.g. for llms.txt workflows) is rewritten fromhttps://example.com/index.html.mdtohttps://example.com/.md, which 404s. Only the index page is affected, since no other page hasindex.htmlas a filename prefix; the same CommonMark link works everywhere else on the site. The served HTML is correct; only the client-side rewrite breaks it.Still present in
maintoday, insrc/resources/projects/website/navigation/quarto-nav.js.The
index.html.mdnaming comes fromoutput-file: index.htmlin the page metadata (tools like nbdev set this on every page of the sites they generate).Steps to reproduce
Primary evidence is the live example under "Actual behavior" plus the code above; a minimal project for reproducing:
_quarto.yml:index.qmd(theoutput-fileline gives the alternate format theindex.html.mdname that triggers the bug):Then:
quarto render python3 -m http.server -d _site # the rewrite is skipped on file:, so serve over httpOpen the served index page and inspect the CommonMark link under "Other Formats". Note: on 1.8.25 I could confirm the rendered HTML gets the
index.html.mdlink, but not the client-side rewrite itself, because that version routessite_libsand the.mdtwin outside_sitewhenoutput-fileis set, so the served page loads no JS; the rewrite is confirmed on the 1.9.38-built live site below.Actual behavior
On the live example, the link's
hrefin the DOM is rewritten to/.mdand 404s;data-original-hrefholds the correctindex.html.md: the CommonMark link on https://fastcore.fast.ai/ (generatorquarto-1.9.38) points tohttps://fastcore.fast.ai/.md, while the same link works on every non-index page, e.g. https://fastcore.fast.ai/tour.html.Expected behavior
The link keeps pointing at
index.html.md. The clean-URL rewrite should only stripindex.htmlat the end of the path, while still allowing a query or fragment:Your environment
mainand in thequarto-nav.jsshipped with 1.8.25Quarto check output
Quarto 1.8.25 [✓] Checking environment information... Quarto cache location: /Users/jhoward/Library/Caches/quarto [✓] Checking versions of quarto binary dependencies... Pandoc version 3.6.3: OK Dart Sass version 1.87.0: OK Deno version 2.3.1: OK Typst version 0.13.0: OK [✓] Checking versions of quarto dependencies......OK [✓] Checking Quarto installation......OK Version: 1.8.25 Path: /Applications/quarto/bin [✓] Checking tools....................OK TinyTeX: (not installed) Chromium: (not installed) [✓] Checking LaTeX....................OK Tex: (not detected) [✓] Checking Chrome Headless....................OK Using: Chrome found on system [✓] Checking basic markdown render....OK [✓] Checking Python 3 installation....OK Version: 3.13.2 Jupyter: 5.9.1 [✓] Checking Jupyter engine render....OK [✓] Checking R installation...........(None)