Repository navigation
Conversation
Sets up a rspress 2.0.0-beta.21 site under rspress/ with EN/FR locales and 26.10/25.10 versioning. Migrates the full getting-started section (84 files) for all 4 lang×version combos, with tabs, homepage components, and proper sidebar configuration.
Extend migration from getting-started-only POC to all 22 sections (~325 files per lang/version combo). Key additions: - migrate.py: recursive migration of all .md/.mdx source files + full assets - Sidebar auto-generated from versioned_sidebars JSON + FR label translations - rspress.config.ts now imports sidebar from src/sidebar.ts - transform(): fix indented code fences, normalize languages (SQL→text, XML→text, phpconf/apacheconf→bash), strip @site/ imports, remove HTML comments in MDX, decode %20 in asset paths - Asset files with spaces renamed to hyphens to satisfy rspack resolver
Replace auto-migrated placeholder index.md with proper HomePage component pages mirroring the 26.10 homepage but with /25.10/ links. Also guard migrate.py against overwriting hand-crafted version index files.
In rspress v2 multiVersion, replaceVersion() only strips the version prefix from the current URL when current != default. If sidebar links use /26.10/... and the user switches to 25.10, the result is /25.10/26.10/... (double prefix). Fix: default version (26.10) sidebar links and homepage/nav links now use no version prefix (/getting-started/welcome instead of /26.10/...). Sidebar key changes from '/26.10/' to '/' and '/fr/26.10/' to '/fr/'.
- New custom theme (theme/index.tsx) with URL-driven VersionSelector and LanguageSelector. The built-in version selector always read '26.10' due to our docs/<lang>/<version> layout (rspress expects the reverse), and the built-in language selector only showed a globe icon. Both are hidden via CSS and replaced. - Config: search.versioned, enableScrollToTop and per-locale editLink to GitHub. Clear themeConfig.nav since the custom theme provides nav items. - tsconfig: jsx + DOM lib so the IDE typechecks the new theme files. - migrate.py: normalize (../)+assets/... references to the correct depth based on the file's location, and skip FR-only files with no EN counterpart (they pulled in stale broken asset paths). - Remove 8 already-migrated FR orphan files the new filter would now skip.
- Add pp (Monitoring Connectors) and cloud migration to migrate.py: 745
pp files and 119 cloud files per language, plus their CommonJS sidebar
files loaded via node. Factor the per-tree migration loop into
_migrate_tree() so versioned-docs, pp and cloud share the same code path
(orphan FR filter, asset copy, asset-with-spaces rename, asset-ref depth
normalization).
- generate_sidebar: include /pp/, /cloud/ and their /fr/ variants, and
emit non-default keys (/25.10/, /pp/, /cloud/, /fr/25.10/, ...) before
the default keys (/, /fr/). rspress sidebar matching is first-match so
the default `/` key would otherwise swallow every nested request.
- Tighten the code-fence language regex so inline triple-backtick spans
like ```rrdcached``` is not supported. don't get falsely treated as
fence openers. Trailing fence attributes (e.g. ```bash {1,3}) are
preserved by capturing them.
- Add shiki aliases for languages not bundled in rspress v2 beta:
smarty/csv/txt → text, cmd → bash.
- theme: replace the external cloud link with a local /cloud/... link
(now that the cloud docs are migrated locally).
- src/sidebar.ts and rspress/docs/{en,fr}/{pp,cloud} regenerated.
- Add LM_SOURCE_{EN,FR}, LM_SIDEBAR_JS, LM_FR_LABELS_PATH constants and a
migrate_logmanagement() call backed by the existing _migrate_tree helper.
- generate_sidebar: register /logmanagement/ and /fr/logmanagement/ in the
non-default key group so they sit before / and /fr/ (rspress's first-match
sidebar resolution).
- theme: add a "Log Management" Link in the top nav, language-prefixed and
pointing at the local /logmanagement/getting-started/welcome.
18 markdown files + 10 assets per language.
The rspress v2 stable line moved to a new npm package name: @rspress/core (the rspress package itself stays at v1.47.x). The CLI binary is still named rspress, only imports and the package name change. Changes: - package.json: replace `rspress@2.0.0-beta.21` with `@rspress/core@~2.0.14`, add `"type": "module"` (eliminates a parse-as-CJS warning + perf overhead rspress v2 prints on startup). - pnpm-workspace.yaml: declare `rspress` as a workspace member so the lockfile tracks its deps properly. Add `minimumReleaseAgeExclude` for `@rspress/core` and `@rspress/shared` so the 7-day minimum-release-age rule doesn't block picking up fresh @rspress/core releases. - rspress.config.ts: switch `defineConfig` import to `@rspress/core`. The `markdown.checkDeadLinks` option moved to `markdown.link.checkDeadLinks` in the v2 stable API. Add an opt-in Rsdoctor integration via `builderConfig.tools.rspack` — set `RSDOCTOR=true pnpm build` to instrument the build and open the analysis dashboard. - theme/index.tsx: switch to named imports from `@rspress/core/theme-original` per the v2 breaking change notice (the previous `default` export from `rspress/theme` is gone; the migration is named exports from `theme-original`). - migrate.py: rewrite injected `<Tabs>/<TabItem>` imports to point at `@rspress/core/theme` instead of `rspress/theme`. All ~2005 affected MDX files regenerated. - Add `@rsdoctor/rspack-plugin` as devDependency (pinned to ^1.5.12 because 1.5.13 is too recent under minimumReleaseAge).
Bring the Rspress documentation visually in line with the production Docusaurus site (docs.centreon.com) for both style and navigation: - Add the Centreon navbar logo (light/dark variants) and favicon. - Set the brand palette via a global stylesheet: Centreon blue (#2213e2) in light mode, green (#37d6ae) and navy background (#00003d) in dark mode, overriding the default Rspress theme vars. - Load the site typography: Red Hat Display for body text and Esphimere for headings. - Tint blockquotes and inline code with the brand color, and add a footer with the corporate links and copyright. Font faces are referenced through paths relative to the stylesheet so Rspack resolves and emits them; root-absolute url() paths failed module resolution and dropped the whole global stylesheet. Assisted-by: Claude Code (claude-opus-4-8)
Continue the visual alignment with the production Docusaurus site (docs.centreon.com): - Highlight code with the github-light / dracula Shiki themes, matching the Prism themes used on the Docusaurus site. - Enable click-to-zoom on documentation images via medium-zoom, re-attaching on each navigation and tinting the overlay per theme (white in light mode, Centreon navy in dark mode). - Render a global footer on documentation pages (corporate links, logo and copyright) through the DocLayout afterDocFooter slot. - Raise the navbar height to 96px to match the Docusaurus header. The official @rspress/plugin-medium-zoom targets the rspress 1.x runtime and is incompatible with 2.x, so the medium-zoom library is wired up directly in the custom theme instead. Assisted-by: Claude Code (claude-opus-4-8)
Two issues surfaced by visual review of the rendered site: - Logos (navbar + footer) and homepage images were broken because the assets lived in rspress/public, but rspress serves the public folder located under the doc root (docs/public). Move images to docs/public/img and keep the fonts bundled by Rspack under styles/fonts (referenced relatively from the global stylesheet). - The navbar showed duplicate language/version selectors: the rule that hid rspress's built-in switchers targeted the obsolete .translation class. In rspress 2.x NavLangs/NavVersions render as plain .rp-nav-menu__item elements inside .rp-nav__others, so hide those while keeping the appearance toggle and social links. Assisted-by: Claude Code (claude-opus-4-8)
Clicking any sidebar entry on a 26.10 (default version) page led to a 404. The migration keyed the default version under '/' with version-less links (/getting-started/foo), assuming rspress would serve the default version at the root. It does not: pages are only served under /<version>/..., and the custom version switcher (VersionAwareNav) already builds /<version>/... links. Version-less URLs are unrouted and 404. Key the default version like the others (/26.10/ and /fr/26.10/) with version-prefixed links, in both migrate.py and the generated src/sidebar.ts. Non-default versions, pp, cloud and logmanagement are unchanged. Assisted-by: Claude Code (claude-opus-4-8)
On viewports below 1280px the custom version-aware nav rendered its links inline, so they overflowed and overlapped the logo. Collapse it into a hamburger button at the top right that opens a panel with the product links, the version and language selectors, and the appearance toggle. rspress's own mobile hamburger is hidden so only one burger is shown. The desktop layout (>=1280px) is unchanged. Assisted-by: Claude Code (claude-opus-4-8)
Add the Experience Monitoring (XM) product documentation, migrated from Docusaurus like the other standalone trees (pp, cloud, logmanagement): English and French content plus assets, served under /experience-monitoring/ and /fr/experience-monitoring/ with their own sidebar sections. migrate.py gains the sources, a migrate_experience() step and the sidebar generation for it. This is needed so the product switcher can link to Experience Monitoring without a 404. Assisted-by: Claude Code (claude-opus-4-8)
Add a grid (apps) icon at the top right that opens a product switcher, mirroring docs.centreon.com: Infrastructure Monitoring (IM), Experience Monitoring (XM) and Log Management (LM), each with its coloured initials badge. Infrastructure Monitoring is version-aware. Experience Monitoring is also added to the mobile burger panel so it stays reachable on small screens. Assisted-by: Claude Code (claude-opus-4-8)
Derive the current product family (Infrastructure Monitoring, Experience Monitoring, Log Management) from the URL and show only that family's sections in the navbar header: Infrastructure Monitoring keeps OnPrem / Cloud / Connectors, while Experience Monitoring and Log Management show only themselves. Show the version selector only on actually-versioned pages (the on-prem docs). It is now hidden on Experience Monitoring and Log Management — as well as Cloud and Connectors — where versions don't exist and switching would 404. The product switcher highlights the active family and the mobile panel mirrors the same product-aware logic. Assisted-by: Claude Code (claude-opus-4-8)
Lay the navbar out like docs.centreon.com: the product sections move to the left next to the logo (with the active one highlighted), and the right cluster is ordered Search, version, language, appearance toggle, product switcher. The version selector gains the star marker. rspress's built-in 'others' group is fully hidden since the appearance toggle is now rendered in our own cluster in the right position. Assisted-by: Claude Code (claude-opus-4-8)
The homepage cards still linked to docs.centreon.com (and the Infra OnPrem link was version-less, hitting a 404). Now that Experience Monitoring, Cloud, Connectors and Log Management are all migrated, repoint every card link to the local pages: Infra OnPrem to the versioned /26.10 path, the others to their product trees. Docusaurus /category/ links are mapped to real pages (digital sobriety, the OpenTelemetry collector page). English and French homepages updated. Assisted-by: Claude Code (claude-opus-4-8)
The footer was attached to the doc layout's afterDocFooter slot, so it only showed on documentation pages and was missing from the custom homepage. Move it to the Layout bottom slot so it renders full-width at the bottom of every page (homepage included), matching the docs.centreon.com footer. Assisted-by: Claude Code (claude-opus-4-8)
The language selector always inserted a /<version>/ segment, so switching language off the on-prem docs went to broken targets: from the homepage it landed on /fr/26.10 instead of the French homepage /fr, and on cloud/connectors/experience/log management pages it produced /fr/26.10/<tree>/... (404). buildPathname now only adds the version on versioned pages, so language switching preserves the current location everywhere (homepage included). Assisted-by: Claude Code (claude-opus-4-8)
Images are the largest part of the output (~96 MB) and are served as-is, so gzip can't shrink them — unlike JS, reducing them cuts the deployed bundle and per-page transfer directly. Add @rsbuild/plugin-image-compress to the builder config to compress PNG/JPEG/ICO at build. Result: PNG output 71.5 MB -> 33.4 MB (-53%), total emitted 154 MB -> 114 MB gzipped (-40 MB), for +8s build and no visible quality loss. GIF/SVG are left untouched. Assisted-by: Claude Code (claude-opus-4-8)
Images were already compressed at build, but GIF and MP4 have no build-time codec and were served raw at full size. Optimize them in the migration with vendored binaries: - GIFs via gifsicle (-O3 --lossy=80): output 24.1 MB -> 15.5 MB. - The demo video via ffmpeg/libx264 (crf 30, 128k audio): 20.8 MB -> 3.5 MB. Combined with the earlier image compression, the deployed bundle drops from 154 MB to 87 MB gzipped (-43%). migrate.py gains an optimize_media() step (no-op when the tools are absent) and ffmpeg-static/gifsicle are added as dev tooling. No visible quality loss. Assisted-by: Claude Code (claude-opus-4-8)
Build the rspress docs in CI and deploy a Cloudflare Pages preview on every PR touching rspress/, posting the URL as a sticky comment. Each PR gets its own stable preview URL; deploying prebuilt assets via wrangler doesn't use the Cloudflare build quota, so it scales to many concurrent PRs for free. Actions are SHA-pinned (reusing the repo's existing pins); wrangler runs via pnpm dlx so no extra action needs pinning. Previews are skipped for fork PRs (no access to secrets). Requires a maintainer to create the Cloudflare Pages project 'centreon-docs-preview' and set CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID. Assisted-by: Claude Code (claude-opus-4-8)
…imit The French search index (25.07 MiB) exceeds Cloudflare Pages' 25 MiB per-file hard limit, which would fail the preview deployment. Drop code blocks from the search index only on preview builds (PREVIEW_BUILD=true, set by the preview workflow): the fr index drops to 22.8 MiB, comfortably under the limit. Staging and production keep the full search index (code blocks included) since they deploy to self-hosted infra with no such limit. Assisted-by: Claude Code (claude-opus-4-8)
…ning) - Make the nav dropdowns keyboard- and screen-reader-accessible: real <button> trigger with aria-haspopup/aria-expanded, open on focus/click, close on Escape and focus-out (the mobile burger was already accessible). - Give the homepage social links an accessible name (alt + aria-label). - Anchor familyOf()/activeSection() on the path prefix (after lang/version) instead of substring matching, so doc slugs containing cloud/pp/... aren't misclassified. - Pin wrangler via the lockfile (devDependency) and call it with pnpm exec instead of fetching the latest at runtime with pnpm dlx in a job holding the Cloudflare token. - Log ffmpeg/gifsicle stderr on failure in migrate.py and drop an unused var. Assisted-by: Claude Code (claude-opus-4-8)
Contributor
|
Set output.minify.jsOptions.minimizerOptions.compress.passes to 1 (rspack defaults to 2 since web-infra-dev/rspack#8853). Minification is the dominant build cost; one pass recovers a chunk of that time with no measurable size change (JS stays 176 MB raw / 21 MB gzipped — the gzipped transfer is already near-optimal). Assisted-by: Claude Code (claude-opus-4-8)
Extract react and node_modules into dedicated lib-react/lib-vendor chunks so the browser keeps them cached across deployments. index.js changes on every docs update; vendors rarely do. Merges with rspress's existing styles cacheGroup (deep-merged, preserved).
# Conflicts: # pnpm-lock.yaml
Also bump @rsdoctor/rspack-plugin, wrangler, and align @types/node with Node 24.
Rspress 2.0.x warns about i18n keys missing for fr and falls back to English (search, outline, prev/next...).
rspress/docs is generated by migrate.py, so its git history only holds migration commits; resolve each page to its source file like Docusaurus' showLastUpdateTime. The preview checkout fetches the full (blobless) history; also move it to Node 24.
Pages are now pre-rendered (relative image paths resolve fine in 2.0.23) and served without the .html extension, like docs.centreon.com. SSG runs one worker per CPU, so the preview build is pinned to 2 CPUs to stay within the runner's 16 GB (15.3 GB peak measured locally, 8 min 16 s).
…cusaurus migrate.py now post-processes the migrated pages: - /docs/... (latest core version on docs.centreon.com) and /<version>/... absolute links become file-relative, as rspress strips the version segment; - relative links Docusaurus resolves from the plugin content root; - URL-relative links written for trailingSlash (../foo/) resolve from the file; - linked downloadable files (.sql, .pdf, .cnf) are published to docs/public/. Those 8,000+ links were rendered as-is and returned 404 on the rspress site.
Like Docusaurus' onBrokenLinks: throw. Links already broken in the Docusaurus sources are listed explicitly. Anchors are not checked: rspress does not see headings nested in JSX (Tabs) and would report false positives.
SSG got the 16 GB GitHub-hosted runner killed mid-build; it stays enabled for other builds (15 GB peak measured with 2 CPUs). Retry wrangler deploys on Cloudflare API rate limiting (code 10429), which failed the last two runs.
migrate.py converts the migrated PNGs with the same palette quantization as the build's PNG compression, then encodes them as lossless WebP and updates the page references. Images served drop from 33.3 MB (quantized PNG) to 20.3 MB; 18 PNGs that cannot be encoded or grow stay as-is.
The default theme renders every sidebar entry and hides collapsed groups with CSS, so each SSG page carried the whole section sidebar (132 KB on a 26.10 page). The ejected Sidebar renders a group's children once it has been expanded, like Docusaurus: HTML output drops from 829 MB to 372 MB (70 -> 45 MB gzipped). Only SidebarGroup.tsx differs from the rspress 2.0.23 eject; the CSS files are rspress' compiled ones.
26.10 and 25.10 are plain sections sharing one search index, so every query returned both versions. Keep the current version's results (the latest one outside versioned docs), like docs.centreon.com.
Like Docusaurus for Markdown images. Without loading="lazy", React preloaded every image of the page in the SSG <head>, competing with critical resources.
The rspress migration copies documentation pages whose example values (API responses, public key thumbprints, placeholders) predate the secrets scan. Refs: MON-212387
7 tasks
- Drop the page fields only the unused Overview component reads (toc, title, frontmatter) from the page list in the main bundle, and give each locale only its own sidebar sections (rspress duplicated the whole sidebar into every locale): index.js 6.6 MB -> 2.1 MB, 821 -> ~280 KB gzipped. - Serve Esphimere as WOFF2 (74 -> 25 KB per weight) and self-host Red Hat Display with @fontsource instead of a render-blocking Google Fonts import. - Cloudflare Pages _headers: hashed /static/ assets are immutable.
…zoom - Footer: full-width band with the links on one side and the logo and copyright on the other, Esphimere bold links, inverted colors on doc pages and side by side on mobile, like the Docusaurus footer. - The custom medium-zoom hook and rspress' built-in plugin both bound the doc images (.rp-doc.rspress-doc), opening two overlays: keep the built-in one, whose --rp-c-bg overlay follows the theme (white / Centreon navy). - Move the nav and footer styles from inline <style> blocks, repeated in every SSG page, to theme/index.css.
The MBI sample report PDFs, SQL and cnf files were copied for every version and language linking them (44 copies, 36 MB of PDFs). migrate.py now publishes identical contents once under /downloads/ and points the links there: 6 files, -18 MB.
The default nav rendered its own switch in the hidden .rp-nav__others and the custom mobile panel was always rendered while hidden: three theme switches (1.1 KB of SVG each) per page. Render nothing in the default nav and the mobile panel only while open.
Each of the ~31,000 code blocks repeated four inline SVGs (copy, copied, wrap, wrapped) in the SSG HTML. The theme overrides these icons with empty spans drawn by a CSS mask defined once, with the same paths.
Docusaurus resolves [](/path/page.md) from the docs plugin content root; the experience-monitoring release notes use it.
Re-run migrate.py on the current Docusaurus sources: descriptions added to the frontmatter, ITSM pages reorganized into ticketing, new Map, CMA and RUM pages, removed pages.
Use the site fonts instead of a system font stack and update the cards from src/pages/index.js (no more Log Management BETA, new STM and RUM entries).
Like docs.centreon.com: breadcrumbs (home, product section, sidebar groups, current page) and a version badge above the title, sidebar groups leading to the current page colored, Esphimere bold navbar items and no section links on the home page.
Values measured on docs.centreon.com: dark pill search box, 18px sidebar with the active item colored instead of highlighted, 18px dark content text, 48px bold h1, no rule above the first h2, bordered tables, h3-deep 14px outline, smaller headings under 576px. Selectors are prefixed with html because the global styles load before rspress' component styles.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a parallel Rspress (v2) documentation site under
rspress/, mirroring docs.centreon.com, without changing the current Docusaurus production site.Target version (i.e. version that this PR changes)