2. Docsify Initialization Order and Site Navigation Mounting
The English HTML shell is site/index.html, and the Japanese shell is site/ja/index.html. The principal elements in each shell’s body are the Docsify mount point #app, the language-specific window.RT configuration, and the scripts required at runtime. The HTML shell does not contain the site navigation markup.
<body class="loading">
<div id="app"></div>
<script>
window.RT = {
// Language, public paths, labels, and other settings
};
</script>
<script src="/ai/app.js"></script>
<script src="/ai/vendor/docsify/docsify.min.js"></script>
<script src="/ai/vendor/docsify/search.min.js"></script>
</body>The loading order must place app.js before the Docsify core script. Docsify 5 reads window.$docsify during initialization. If the configuration is defined after the core script, the sidebar and plugins are not enabled.
Scope of the $docsify Configuration
The following excerpt shows the settings defined by app.js that relate to the site navigation.
window.$docsify = {
name: "Real Terms",
nameLink: RT.publicBase + "#/",
basePath: RT.contentBase,
homepage: "README.md",
loadSidebar: true,
relativePath: false,
auto2top: true,
alias: docsifyAliases,
search: {
placeholder: S.searchPlaceholder,
noData: S.searchNoData,
},
// plugins and other settings are omitted
};Because loadNavbar is not specified, it remains disabled by default. The search object sets display strings, and search.min.js inserts the search interface into the sidebar. Search is not placed in the site navigation.
The siteChrome Plugin
The siteChrome plugin is registered first in the Docsify plugins array. It uses three hooks.
function siteChrome(hook) {
var syncNavAfterRoute;
hook.afterEach(function (html, next) {
// Docsify #y() scrollIntoViews the first heading unless it already
// has tabindex. Keep preventScroll focus, skip the 64px nudge.
html = html.replace(/<(h[1-6])(\s[^>]*)?>/gi, function (match, tag, attrs) {
attrs = attrs || "";
if (/\btabindex\s*=/i.test(attrs)) {
return match;
}
return "<" + tag + ' tabindex="-1"' + attrs + ">";
});
next(html);
});
hook.ready(function () {
ensureSiteNav();
syncNavAfterRoute = setupSiteNavScrollReveal();
});
hook.doneEach(function () {
if (syncNavAfterRoute) {
syncNavAfterRoute();
}
});
}afterEach
Addstabindex="-1"to headings in the article HTML generated by Docsify. Docsify moves the first heading into the viewport, but if the heading already hastabindex, it focuses the element without scrolling. This prevents the first heading from moving behind the fixed 64px navigation.ready
CallsensureSiteNav()once after Docsify initialization completes, then registers the scroll-dependent visibility control.doneEach
Restores the site navigation to its visible state after each route is rendered. Chapter 4 describes this behavior in detail.
Inserting Outside #app
ensureSiteNav() returns the existing .eg-site-nav element if one is present. Otherwise, it creates a header and inserts it at the beginning of document.body.
document.body.insertBefore(header, document.body.firstChild);Docsify updates its rendering area whenever the route changes. If the site navigation were placed inside #app, rerendering could remove the element or prevent it from retaining its menu and scroll-dependent visibility state. Placing it directly under document.body separates the site navigation from Docsify rerendering.
The following diagram summarizes the initialization order.
The next chapter describes the generated header DOM structure and the role of each element.