fix(docsify): use hash routing so lesson URLs load directly by mcalihe · Pull Request #769 · microsoft/AI-For-Beginners · GitHub
Skip to content

fix(docsify): use hash routing so lesson URLs load directly - #769

Open
mcalihe wants to merge 2 commits into
microsoft:mainfrom
mcalihe:claude/hungry-cartwright-717c3e
Open

mcalihe wants to merge 2 commits into
microsoft:mainfrom
mcalihe:claude/hungry-cartwright-717c3e

Conversation

@mcalihe

@mcalihe mcalihe commented Oct 17, 2026

Copy link
Copy Markdown

Problem

The docs site uses Docsify with routerMode: 'history', but GitHub Pages has no fallback for single-page apps. Navigating inside the site works. Opening, reloading or sharing a lesson URL does not: GitHub's 404 page comes back instead.

Example: https://microsoft.github.io/AI-For-Beginners/lessons/3-NeuralNetworks/03-Perceptron/README

Fix

Switch to Docsify's default hash router. Lesson URLs become /AI-For-Beginners/#/lessons/.... Every request then hits index.html, which GitHub Pages serves with HTTP 200.

Switching the router alone would break about 1,800 images. 35 raw HTML <img src="images/..."> tags in the English lessons and about 1,780 in translations/ are written relative to their markdown file. The translated pages also contain about 80 raw <a href="../..."> links. Docsify doesn't rewrite raw HTML. With the hash router the document URL is the site root, so those paths would resolve against the wrong folder. A small afterEach plugin resolves them against the current markdown file instead, the same way Docsify already handles markdown images and links. It runs before the HTML is inserted into the page, so wrong URLs are never requested.

Home-page section links from the old router (/?id=section) are redirected to #/?id=section, so links already shared keep working.

Why not a 404.html fallback?

A copy of index.html as 404.html would keep history URLs and the relative raw HTML paths working. But:

  • Every deep link would still be served with HTTP 404. Search engines don't index those pages, and link checkers report them as broken.
  • Chrome logs the 404 document response as a console error on every deep-link load.
  • The Docsify config would have to be kept in sync across two HTML files.

Hash routing works on any static host, with no error responses and no second file.

Trade-offs

  • URLs contain #/. Lesson URLs in the old history format never loaded directly, so no working link breaks.
  • History-format lesson URLs that were shared before (/AI-For-Beginners/lessons/.../README) keep returning 404, as they do today.

Also in this PR

lessons/3-NeuralNetworks/README.md linked to 05-Frameworks#overfitting, which resolves to a non-existent 05-Frameworks.md on the site. The link now points to 05-Frameworks/README.md#overfitting.

Verification

Tested with a local static server that behaves like GitHub Pages (case-sensitive paths, tries path, path.html and path/index.html, otherwise 404, served under /AI-For-Beginners/). The baseline reproduced the live 404. Tested twice: with this branch as it is (Docsify 4.13.1), and merged with #768 (Docsify 5.0.0), which merges without conflicts.

  • A direct load and a reload of #/lessons/3-NeuralNetworks/03-Perceptron/README render the lesson, and its raw HTML images load.
  • Clicking in-content links works (Perceptron → lab), including the fixed Overfitting link. It opens 05-Frameworks/README?id=overfitting and scrolls to the heading.
  • A direct load of ?id= URLs scrolls to the heading, for lesson pages and the home page. Legacy /?id=quizzes is rewritten to #/?id=quizzes.
  • Raw <a href="../lessons/2-Symbolic/README.md"> in translations/README.ja.md opens the right page.
  • Sweep of all 61 English pages plus 4 translated pages: every page renders, all 202 content images load, the server returned no 404s, and the console shows no errors.

Notes

  • Links to .ipynb files show Docsify's "404 - Not found" page when clicked, both on the live site and with this change. Not addressed here.
  • With build(docsify): upgrade docs site to Docsify v5 #768, Docsify 5 builds heading ids differently from v4: emoji are dropped, so 🤝-contributing becomes -contributing. Old ?id= links to those headings won't scroll under v5, whichever router is used.

GitHub Pages has no fallback for single-page apps, so with routerMode
'history' every lesson URL returned GitHub's 404 page when it was
opened directly, reloaded or shared. The default hash router keeps
every request on index.html, which GitHub Pages serves with HTTP 200.

Lessons embed raw HTML such as <img src="images/..."> and translated
pages link with <a href="../...">. Docsify does not rewrite raw HTML,
and with the hash router the document URL is the site root, so an
afterEach hook resolves those paths against the current markdown file,
the same way Docsify resolves markdown images and links.

Links to sections of the home page from the old router (/?id=...) are
redirected to their hash route so they keep working.
05-Frameworks#overfitting resolves to a non-existent 05-Frameworks.md
on the docs site. Point it at the lesson README instead.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant