`#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>
Final ingredient of the v1.2.2 stable release: flip version.txt from
1.2.1 to 1.2.2 so the stable channel's update notifier picks it up
on every running install, ship the consolidated v1.2.2 entry on both
CHANGELOG.md (English) and lang/es/CHANGELOG.md (Spanish), and add
the GitHub link to Jonatan Castro on the contributors page.
CHANGELOG.md entry (and its ES mirror) consolidates the four v1.2.1.x
betas into a single stable note grouped by theme — Health Monitor
configurability, Apprise full feature parity, LXC update detection,
Coral TPU latest upstream drivers, performance optimizations (smartctl
scheduler, fail2ban cache, lxc-info /proc), HTTPS terminal handshake,
PVE 9.x kernel update detection, NVIDIA installer improvements, i18n
documentation site — plus an Acknowledgments section crediting
@jcastro (5 direct commits), @pespinel (1 commit) and @ghosthvj
(field reports that shaped the GPU + Coral work).
contributors/page.tsx: Contributor interface now carries an optional
`githubUrl`; when set, the displayed name is wrapped in an
ExternalLink to that URL (target=_blank). Jonatan Castro's entry gets
`githubUrl: https://github.com/jcastro` so users can reach his repos
from the testers grid.
After this PR merges:
- Users running `menu` will be offered the 1.2.2 upgrade
- proxmenux.com/en/changelog and /es/changelog ship the new entry
(deploy.yml triggers because CHANGELOG.md, lang/** and web/** are
all touched)
- Jonatan Castro's name on the contributors page becomes clickable
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Last commit renamed images/avatars/JF_Car.png to JF_Carr.png on the
assumption the file name was the typo. It wasn't — the user's name
is actually JF_Car. Rename the file back and update the display
name + avatar URL in the contributors page accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the temporary github.com/<handle>.png placeholders with the
project's standard raw.githubusercontent.com/.../images/avatars/<name>.png
pattern used by every other contributor on the page.
Added avatar files:
- images/avatars/heriberto.png
- images/avatars/JF_Carr.png (renamed from JF_Car.png on disk so the
filename matches the display name)
- images/avatars/rafapuerta.png
- images/avatars/JcMinarro.png
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributors page (app/[locale]/docs/about/contributors/page.tsx):
add heriberto, JF_Carr, rafapuerta and JcMinarro to the testers
grid. All with the "testing" role and GitHub's default avatar URL
(https://github.com/<handle>.png) so the entries work immediately
without requiring custom avatar files. Swap to a per-contributor
/images/avatars/<name>.png later if/when custom artwork is ready.
deploy.yml triggers: drop `guides/**` (the legacy /guides/[slug]/
page that read those markdown files was removed in PR #211 — the
folder no longer affects what the web renders) and `scripts/**`
(the bash scripts get rsynced into public/scripts/ during prebuild
but they are downloaded by users via install_proxmenux.sh, not
browsed via the doc site, so a stale copy is harmless). Add
`lang/**` so future translated CHANGELOG / docs (e.g. the Spanish
CHANGELOG just shipped in PR #217) auto-deploy.
Local build verified: 232 pages, 14450 indexed words, no errors.
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>
The previous deploy went live but every visitor hit a 404. Root cause:
GitHub Pages serves the URL `/foo/` by looking for `out/foo/index.html`.
Next.js's static export with the default `trailingSlash: false` instead
emits `out/foo.html`, which Pages only serves for `/foo` (no trailing
slash).
The i18n root redirect in app/page.tsx points users at
`/<defaultLocale>/` (with slash) because that is what next-intl's
`<Link>` components generate. So every visitor landed on
`https://proxmenux.com/en/` → Pages looked for `out/en/index.html`,
did not find it (the export had emitted `out/en.html`), and fell back
to `out/404.html`. Result: the site looked deployed but every page
was a Next.js 404 template.
Setting `trailingSlash: true` makes the export emit
`out/<route>/index.html` for every page — locale roots
(`out/en/index.html`, `out/es/index.html`), nested doc pages
(`out/en/docs/monitor/dashboard/settings/index.html`, etc.), changelog,
guides — so Pages serves them directly.
Local verification: 232 pages built, root redirect intact at
out/index.html, and every locale + doc + guide URL now resolves to
its own index.html.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two regressions surfaced after the 1.2.2 release merge to main, both
in workflows that auto-trigger on push to main:
* Deploy to GitHub Pages — build failed with `pagefind: not found`
(exit 127) after Next.js prerendered all 241 routes. pagefind was
not declared in web/package.json; the local build only worked
because the project root had its own package.json with pagefind
as a devDep (the one we just gitignored in the previous commit).
Add `pagefind: ^1.5.2` to web/package.json devDependencies and
regenerate web/package-lock.json so `npm ci` in CI puts the
binary at web/node_modules/.bin/pagefind.
* Build ProxMenux Monitor AppImage — failed at the first step with
`mkdir: cannot create directory '/var/cache/proxmenux-build':
Permission denied`. The cache path was hardcoded to /var/cache/,
which is writable when the script runs as root (the .50 host
manual build) but not as the unprivileged GitHub Actions runner.
Switch to `${XDG_CACHE_HOME:-$HOME/.cache}/proxmenux-build/` —
works identically in both environments.
Verified locally: `cd web && npm ci && npm run build` produces 2804
files in out/, 231 pages indexed by pagefind, root redirect intact.
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.