fix(docs): the language switch keeps the page the reader is on - #590
Conversation
`_navbar.md` links to `/` and `/pt-br/`, so switching the language from anywhere in the site dropped the reader on a home page and made them find their way back. The navbar now points each of its two links at the page on screen in that language, on every route change: `/utilities` and `/pt-br/utilities` stand for each other, and the query string and the anchor go along, so a reader following a deep link keeps their place. The link of the language being read carries `aria-current` and the class docsify already styles as the active navbar entry. Both trees hold the same pages, page for page, which is what `scripts/site.ts` already asserts in every hreflang link and in the sitemap, so a translated route is a page that answers. The home pages are the exception, since they are not translations of each other (`/` is the README and `/pt-br/` shows pt-br/getting-started through `alias`), and so is a route no language has: both send the reader to the other language's home instead of to a URL known to be missing. The links are rewritten in place rather than written as markup, so `_navbar.md` stays the source of the labels and their order; docsify answers its own navbar request after the hook on some routes, so the navbar is watched and written again whenever it comes back from the Markdown.
|
@coderabbitai review |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review. 📝 WalkthroughWalkthroughDocsify now synchronizes English and Portuguese navbar links with the current route. It preserves query strings and anchors, applies language-specific fallbacks, updates active link state, and reapplies changes after navbar mutations. ChangesLanguage-aware navbar routing
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to This documentation-only change improves language navigation while preserving route context, and no actionable production risk is currently identified. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🧪 Generate unit tests (beta)
🛠️ Fix failing CI checks 💡
Comment |
✅ Action performedReview finished.
|
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #590 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 186 186
Lines 2069 2069
Branches 613 613
=========================================
Hits 2069 2069
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
What
Switching the language on the documentation site sent the reader to a home page:
docs/_navbar.mdlinks to
/and/pt-br/, and those are the only two URLs the navbar ever had. The switch nowkeeps the page on screen:
/utilitiesand/pt-br/utilitiesstand for each other, and the querystring and the anchor go along, so a reader who followed a deep link keeps their place.
A small docsify plugin in
docs/index.html, in the shape of the ones already there, rewrites thetwo links on every route change (
hook.doneEach).Shape, and why
_navbar.mdstays the source of thelabels, their order and their language names; only each
hrefchanges. A link is recognised bythe href the Markdown gives it (
/is English,/pt-br/is Portuguese) and remembers itslanguage in a
data-languageattribute, so it is still recognised once it points at a page, andany other link someone adds to the navbar later is left alone.
_navbar.mdon its own, and on some routes thatrequest answers after
doneEachand puts the Markdown's links back (reproduced below on thebrowser's back button and on
/). The plugin observes the navbar and writes the links againfrom the same destinations whenever docsify re-renders it. This is why the plugin keeps the
route it computed in a closure instead of only acting inside the hook.
?id=, and a link from outside may carry a#; both are carried over. The history router leaves a#fragment insideroute.path, so thepath is translated without it (otherwise the fragment ended up in the href twice).
aria-current="page"and theactiveclass docsifyalready styles for a navbar entry (
.active :is(.app-nav a)in its core theme), so it needs nonew CSS: the language being read shows in the theme green.
The page that does not exist in the other language
Checked rather than assumed: the two trees hold the same pages, page for page
(
docs/_sidebar.mdanddocs/pt-br/_sidebar.mdlist getting-started, utilities, the four guidesand the v1-to-v2 migration;
docs/anddocs/pt-br/hold the same Markdown files). That pairingis already asserted elsewhere:
scripts/site.tswrites anhreflangpair and a sitemap entry forevery page on exactly this rule. So a translated route is a page that answers, and the link is
kept as is; if it ever 404s, the sitemap and the hreflang links are wrong too, and that is a
docs bug to fix rather than something the navbar should paper over.
Two routes have no translation, and both send the reader to the other language's home:
/is the README and/pt-br/showspt-br/getting-startedthroughalias./↔/pt-br/, which is also what thealiasconfigrequires — never
/pt-br/READMEor a bare/pt-br. The place within the page is dropped here,since it is a different document.
instead of offering a second URL that is known to be missing, both links become the home pages
and the reader has a way out.
Verification
Built the site (
npm run build:docs) and serveddocs/locally the way GitHub Pages does(a static server resolving
/pagetopage.html), then drove headless Chrome over the DevToolsprotocol, clicking the real navbar links. Observed, for each step, the URL,
<html lang>, therendered
<h1>and both navbar links:/utilities/utilities/utilities(current)/pt-br/utilities/pt-br/utilities/utilities/pt-br/utilities(current)/utilities/utilities(current)/pt-br/utilities/getting-started?id=bundle-size/getting-started?id=bundle-size(current)/pt-br/getting-started?id=bundle-size/pt-br/getting-started?id=bundle-size/getting-started?id=bundle-size/pt-br/getting-started?id=bundle-size(current)/getting-started#bundle-size/getting-started#bundle-size(current)/pt-br/getting-started#bundle-size/pt-br/getting-started#bundle-size/getting-started#bundle-size/pt-br/getting-started#bundle-size(current)///(current)/pt-br//pt-br///pt-br/(current)//(current)/pt-br//guides/schema/guides/schema/guides/schema(current)/pt-br/guides/schema/pt-br/guides/schema/guides/schema/pt-br/guides/schema(current)/pt-br/does-not-exist//pt-br/(current)/pt-br/utilities//pt-br/(current)//(current)/pt-br//utilities→ Português/pt-br/utilities/utilities/pt-br/utilities(current)/utilities/utilities(current)/pt-br/utilities(current) is the link carrying
aria-current="page"and theactiveclass.Step 7 is the case the tree does not actually have: the local server was told to answer 404 for
/pt-br/utilities.mdwhile the English page stayed, which is what a page missing from the othertree would look like. The link is kept and the reader lands on docsify's 404 view (documented
choice above), and the navbar there offers both home pages, which is how 7c gets back.
Nothing else moved: on
/utilitiesthe sidebar still has its 178 links with "Utilities" markedaria-currentandactive, and a search forCPFstill returns its 39 results withCPFfirst.The canonical/hreflang hook is untouched (this plugin only reads
vm.route),npm run build:siteregenerates the page shells from the edited
index.htmlwith no other diff, and the generatedfiles stay out of the repository as
.gitignoreand CONTRIBUTING require.Before the change, on the same build from
main:/utilities,/getting-started?id=bundle-sizeand
/getting-started#bundle-sizeall showed["/", "/pt-br/"]in the navbar, which is the bug.Open points
#fragmentURL (/getting-started#bundle-size, step 3) renders the page shell instead ofthe page: docsify's history router keeps the fragment in the route path and fetches
getting-started#bundle-size.md, which the browser sends as/getting-started. This is whatmaindoes too (verified on the same build without the plugin) and is left alone here; thenavbar link is at least correct now. docsify's own anchors (
?id=, step 2) are unaffected.?id=bundle-sizehas no twinin
pt-br/getting-started(?id=tamanho-do-bundleis the Portuguese one): the reader lands onthe right page at the top, which is what docsify does with an id it cannot find.
/pt-br/...URL the Portuguese link is the one marked as current, sincethat is the tree the URL is in, while the metadata hook leaves
<html lang>alone for a pagethat does not exist. Cosmetic, and only on the 404 view.
answer in this session. Screenshots of the English and Portuguese navbars were taken locally
(
en-utilities.png,pt-utilities.png); GitHub has no way to attach them from the CLI.change. That job checks the base commit out into
base/inside the head tree and then runsnpm run build;tsconfig.jsonexcludesdocs, which does not matchbase/docs, so the buildtype-checks
base/docs/snippets/document-field/_templates/*.ts, the templates that are notvalid TypeScript on their own. Every error in the log is in that folder, which this branch does
not touch, and
npm run buildpasses here. fix(build): the document field templates stop breaking the package build #588 is the fix for it (it renames the templates to.tmpl); this job goes green on a re-run once that lands.