From 3b8019f37a5502410e63c81e63b6c99f22fd0137 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 29 May 2026 09:05:11 +1000 Subject: [PATCH] fix(docs): Use vitepress plugin from NPM for dynamic nav bar (#27498) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(docs): bypass VitePress router interception in DynamicNav links VitePress installs a global click interceptor that catches same-origin clicks and routes them through Vue Router. Cross-version links (e.g. /v1.17/en/ from /main/en/) share the origin but are separate deployments, so Vue Router fails to resolve them and navigation is silently swallowed. Fix by calling window.location.href directly with @click.prevent on all nav links. Signed-off-by: Hamish Willee * refactor(docs): use VitePress internal nav components in DynamicNav Replace the hand-rolled dropdown/link rendering with VitePress's own VPNavBarMenuLink, VPNavBarMenuGroup, VPNavScreenMenuLink, and VPNavScreenMenuGroup. This removes ~140 lines of custom CSS and all manual click/flyout handling; VitePress styles and VPFlyout behaviour are inherited for free. The navigation bug (same-origin links swallowed by Vue Router) is also fixed by this approach: VPLink classifies any https:// href as external and renders a plain tag, bypassing the router interceptor entirely. Remote URL and localStorage key are now read from themeConfig (dynamicNavUrl, dynamicNavCacheKey) so the component can be dropped into any VitePress repo with just a config change. Signed-off-by: Hamish Willee * refactor(docs): derive DynamicNav cache key from URL by default Use the remote URL as the localStorage key when dynamicNavCacheKey is not set. This avoids the need to declare a key in config, keeps the key unique per data source automatically, and means all deployed versions of a site (same origin, different base paths) naturally share one cache entry — which is the desired behaviour. Signed-off-by: Hamish Willee * chore(docs): remove redundant nav:[] from themeConfig VitePress renders no menu items when nav is omitted, so the explicit empty array adds no value now that all items come from DynamicNav. Signed-off-by: Hamish Willee * fix(docs): restore display:flex on DynamicNav bar wrapper Removing the scoped styles during the VitePress-internal-components refactor also removed the flex layout on the wrapper div, causing nav items to stack vertically instead of in a row. Signed-off-by: Hamish Willee * refactor(docs): replace local DynamicNav with vp-dynamic-nav npm package Removes the in-tree DynamicNav.vue and wires up the published vp-dynamic-nav package instead. navbar.json is imported in config.mjs and passed as dynamicNavInitial so it remains the single source of truth for both the initial render and the remote fetch target. Signed-off-by: Hamish Willee --------- Signed-off-by: Hamish Willee --- docs/.vitepress/config.mjs | 5 +- .../theme/components/DynamicNav.vue | 283 ------------------ docs/.vitepress/theme/index.js | 11 +- docs/package.json | 1 + docs/yarn.lock | 5 + 5 files changed, 12 insertions(+), 293 deletions(-) delete mode 100644 docs/.vitepress/theme/components/DynamicNav.vue diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index 0571be397e..e5d0387699 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -1,4 +1,5 @@ import { defineConfig } from "vitepress"; +import navbarData from "./navbar.json"; const getSidebar = require("./get_sidebar.js"); import openEditor from "open-editor"; // Open file locally via edit @@ -159,7 +160,9 @@ export default defineConfig({ */ }, - nav: [], + dynamicNavUrl: + "https://raw.githubusercontent.com/PX4/PX4-Autopilot/main/docs/.vitepress/navbar.json", + dynamicNavInitial: navbarData.nav, socialLinks: [ { icon: "github", link: "https://github.com/PX4/PX4-Autopilot" }, diff --git a/docs/.vitepress/theme/components/DynamicNav.vue b/docs/.vitepress/theme/components/DynamicNav.vue deleted file mode 100644 index e8d0be8a86..0000000000 --- a/docs/.vitepress/theme/components/DynamicNav.vue +++ /dev/null @@ -1,283 +0,0 @@ - - - - - - - diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index 3b90032959..169336981c 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -20,7 +20,7 @@ if (inBrowser) { // Support redirect plugin import Redirect from "./components/Redirect.vue"; -import DynamicNav from "./components/DynamicNav.vue"; +import { createDynamicNav } from "vp-dynamic-nav"; // Tabs: https://github.com/Red-Asuka/vitepress-plugin-tabs import { Tab, Tabs } from "vue3-tabs-component"; @@ -28,14 +28,7 @@ import "@red-asuka/vitepress-plugin-tabs/dist/style.css"; /** @type {import('vitepress').Theme} */ export default { - extends: DefaultTheme, - Layout: () => { - return h(DefaultTheme.Layout, null, { - // https://vitepress.dev/guide/extending-default-theme#layout-slots - "nav-bar-content-before": () => h(DynamicNav), - "nav-screen-content-after": () => h(DynamicNav, { screen: true }), - }); - }, + extends: createDynamicNav(DefaultTheme), enhanceApp({ app, router, siteData }) { app.component("Redirect", Redirect); //Redirect plugin //Tabs: https://github.com/Red-Asuka/vitepress-plugin-tabs diff --git a/docs/package.json b/docs/package.json index 04372fad4a..a315afb7bd 100644 --- a/docs/package.json +++ b/docs/package.json @@ -23,6 +23,7 @@ "medium-zoom": "^1.1.0", "open-editor": "^5.0.0", "vitepress": "^1.6.3", + "vp-dynamic-nav": "^0.0.1", "vue3-tabs-component": "^1.3.7" }, "devDependencies": { diff --git a/docs/yarn.lock b/docs/yarn.lock index 6ddf996df4..44b9aef100 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1747,6 +1747,11 @@ vitepress@^1.6.3: vite "^5.4.14" vue "^3.5.13" +vp-dynamic-nav@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/vp-dynamic-nav/-/vp-dynamic-nav-0.0.1.tgz#4e3f803343d3457a262b5498b06ed2c6172da247" + integrity sha512-7FnKerBRMsqfVLWKPrm7sFFhFIXEbMJY6X1HJ17CvrEacL1al1UXFfXcMB+Vi9o0xdHOMU0e7N6kQQXAfjyLRA== + vue3-tabs-component@^1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/vue3-tabs-component/-/vue3-tabs-component-1.3.7.tgz#b6cc2d3909eeec0bd82b571029050731f6e4ce64"