`#host` and `#lxc-net` are visual sidebar section headers for the
Storage Share Manager page — they group their submenu items in the
sidebar tree but point back at the parent Overview with an anchor,
so they aren't standalone docs the reader advances to. Including
them in the flat Previous/Next sequence produced two regressions:
* On `/docs/storage-share/#host` the Next button targeted `#host`
again, so clicking it didn't move. The earlier hash-tracking fix
intended to catch this, but a `useEffect` with an empty dep array
only runs on mount — and Next.js Link navigations don't fire
`hashchange` when the path changes too, so a cross-page navigation
that lands on `#host` (sidebar click) rendered with hash="" and
re-collapsed to the section header.
* On `/docs/storage-share/lxc-mount-points/` the Next button pointed
at `#lxc-net` instead of advancing to `lxc-nfs-client`, since the
section header sat between the two real pages in the flat list.
Filter out any sidebar entry whose href contains `#` at walk time so
the flat list only carries real pages. With them gone, an anchored
URL collapses to its parent Overview and Next walks straight into
the first subpage. The hash effect + state are no longer needed so
the component drops them, keeping only the pathname-based match.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three changes that fold into the v1.2.2 release PR:
1. AppImage: bump Next.js 15.1.6 -> 15.1.9 (CVE-2025-55182)
GHSA-9qr9-h5gf-34mp / React2Shell is a pre-auth RCE in React Server
Components when Server Functions deserialize attacker payloads. The
ProxMenux Monitor ships Next.js in `output: "export"` mode behind
Flask on :8008, so there is no runtime Next.js server and no
"use server" directive in the source tree — the exploitable path is
not reachable. Bumping to 15.1.9 anyway because OpenVAS and similar
scanners flag the version string from the JS bundle regardless of
architecture; raising the floor removes false-positive noise across
every install. Reported by @rost43 in #219.
2. web/components/ui/doc-navigation.tsx: handle sidebar entries that
point to in-page anchors. The Storage Share Manager sidebar has
entries for `/docs/storage-share#host` and
`/docs/storage-share#lxc-net` as section headers, but
usePathname() does not include the hash so every visit collapsed
to the parent page. As a result Next/Previous on /docs/storage-share
stayed stuck at #host, and Next from .../lxc-mount-points/ pointed
back at #host instead of #lxc-net. Read window.location.hash on
mount (and on hashchange) and try the pathname+hash match before
falling back to the pathname-only lookup. SSR hydrates with an
empty hash and refreshes once mounted — brief render before
hydration is the same as the previous behaviour, so no regression.
3. scripts/help_info_menu.sh: user-side improvement (mirrored from
develop).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR #212 added `trailingSlash: true` to next.config.mjs so GitHub Pages
would serve the locale roots correctly. That changed what usePathname()
returns at runtime — `/docs/.../page/` with a trailing slash — but
the sidebar config (sidebarItems in DocSidebar.tsx) still declares
hrefs without the trailing slash. Every equality check
`pathname === item.href` therefore returned false on every page, and
two things broke:
1. components/ui/doc-navigation.tsx — the Previous/Next bar at the
bottom of every doc page. With `findIndex` returning -1,
`prevPage` was null and `nextPage = allPages[0]` (Introduction).
So every doc page showed "Next: Introduction" regardless of
where the user was.
2. components/DocSidebar.tsx — four comparisons that drove (a) the
highlighted active item in the sidebar, (b) the active-section
auto-open when navigating directly to a nested page, (c) the
leaf-item highlight when the item has no submenu. All silently
broken on every page.
Fix: a `stripTrailingSlash` helper plus a derived `currentPath` that
is compared instead of the raw `pathname`. `collectHrefs(...)` results
are also normalized at the point of comparison so the
`.includes(currentPath)` checks behave correctly.
Verified locally with `npm run build` — 232 pages indexed, no errors.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Full rewrite of the docs site under app/[locale]/ with next-intl
in localePrefix:"always" mode. Every page now exists at both
/en/<path> and /es/<path>; the root / shows a meta-refresh + JS
redirect to /<defaultLocale>/ so GitHub Pages serves something
on the apex URL.
Highlights:
- 107 doc pages migrated to file-per-page JSON namespaces under
messages/en/ and messages/es/. Spanish content is fully
translated (no copy-of-English placeholders).
- New documentation for the Active Suppressions section in the
Settings tab and the per-event Dismiss dropdown in the Health
Monitor modal.
- New screenshots: dismiss-duration-dropdown.png and an updated
health-suppression-settings.png.
- Pagefind integrated for client-side search; index is built on
every CI deploy (not committed).
- RSS feeds: per-locale at /<locale>/rss.xml plus root /rss.xml
for backward compat.
- Removed the dead app/[locale]/guides/[slug]/ route — every
guide now has its own static page and no markdown source
remains.
- Fixed orphan link /guides/nvidia -> /guides/nvidia-manual in
docs/hardware/nvidia-host.
- Removed obsolete components (footer2, calendar, drawer).
Verified locally with `npm ci && npm run build`: 2804 files in
out/, 231 pages indexed by pagefind, root redirect intact, both
locale roots and the new Active Suppressions docs render OK.