Skip to content

Migrate documentation to Astro Starlight#1686

Open
GreenFlux wants to merge 14 commits into
developfrom
docs/astro-migration
Open

Migrate documentation to Astro Starlight#1686
GreenFlux wants to merge 14 commits into
developfrom
docs/astro-migration

Conversation

@GreenFlux
Copy link
Copy Markdown
Contributor

@GreenFlux GreenFlux commented May 28, 2026

Status

Draft. Asking for an early structural look — happy to split this into separate PRs if reviewers prefer:

  1. Astro/Starlight foundation (config, custom components, build pipeline wiring)
  2. Content migration (the 55 guide pages + homepage + 404 moving into src/content/docs/)
  3. Documentation governance docs (CLAUDE.md, README-EDITING.md, README-DEPLOYMENT.md)
  4. starlight-page-actions feature + the right-sidebar UI placement

Currently three logical commits, easiest to review per-commit:

  • e227a2479 — Migrate documentation from VuePress to Astro Starlight
  • ec5c7d126 — Add documentation authoring standards and editing/deployment guides
  • 510fb6d5a — Move page action buttons into the right sidebar

Summary

Replaces the VuePress 1.x docs site with Astro 6 + Starlight 0.38. The previous docs/.vuepress/ configuration stays in place for now since it's no longer wired into the build pipeline — a separate cleanup will remove it.

Site structure

  • Guides, homepage, and 404 now live at docs/src/content/docs/ and are tracked in git (no longer regenerated on every build).
  • API reference under docs/src/content/docs/api/ is the only path still processed by scripts/generate-content.mjs (it normalizes TypeDoc output).
  • Netlify _redirects map preserves the legacy /docs/guide/<slug>.html → clean URLs and is auto-generated.

Custom Starlight component overrides

  • Head (Inter font, example-runner client script), Header (two-row HT-style nav with logo + version pill, search, GitHub stars, primary nav, support dropdown), Footer (link grid + social row), ThemeSelect (sun/moon toggle), PageTitle + PageSidebar (moves the Copy Markdown / Open in ChatGPT / Open in Claude buttons into the right sidebar under "On this page", matching the HT docs layout).

Plugins

  • starlight-theme-rapide (typography + chrome) and starlight-page-actions (page-action buttons + auto-generated .md companions next to each .html).

Authoring governance

  • docs/CLAUDE.md (symlinked from docs/AGENTS.md) — Diátaxis-based authoring rules, frontmatter schema with permanent 8-char IDs, code-example conventions (licenseKey: 'gpl-v3', builder methods), Excel/Google Sheets trademark callouts, and a PR checklist.
  • docs/README-EDITING.md — practical reference for Starlight-native asides, the live-runner HTML pattern, and sidebar registration.
  • docs/README-DEPLOYMENT.md — Netlify build chain, docs:build pipeline, GitHub Actions CI verification.

Build wiring

  • netlify.toml runs npm run docs:build from the repo root and publishes docs/dist.
  • .github/workflows/build-docs.yml runs the same command on PRs and pushes to master, develop, release/**.
  • Root docs:build script chains: bundle-alltypedoc:build-apicd docs && npm ci && npm run build.

Test plan

  • Verify the Netlify deploy preview renders correctly (link will appear in the PR after Netlify builds)
  • Spot-check the homepage, a guide page with a live ::: example block (e.g. /docs/guide/basic-usage), and an API ref page (e.g. /docs/api/classes/hyperformula)
  • Click through the right-sidebar action buttons on a guide page: Copy Markdown copies the page's .md companion, Open in ChatGPT / Open in Claude prefill a prompt
  • Verify the legacy .html URL redirects in _redirects resolve (e.g. /docs/guide/basic-usage.html/docs/guide/basic-usage)
  • Smoke-test theme switching (sun/moon toggle in the header)
  • Confirm npm run docs:build from the repo root completes without errors

Known follow-ups (not in this PR)

  • Remove the now-unused docs/.vuepress/ directory
  • Audit Excel/Google Sheets pages and add the trademark callouts documented in CLAUDE.md §9
  • Wire the docs-assistant chat widget (HT has it, HF would benefit from it; lower priority)
  • Decide whether to add "Print this page" / "Ask AI" buttons to match the full HT page-actions list

Note

Medium Risk
Large docs-platform swap affects production URLs, build/CI (docs:build, Node 22), and all published guide content; runtime library code is largely untouched but deploy breakage would impact every reader.

Overview
This PR replaces the VuePress docs site with Astro 6 + Starlight under docs/, served at /docs with Node 22 (root and docs/.nvmrc).

Content and build: Guide pages, homepage, and 404 move to docs/src/content/docs/ (tracked in git) with Starlight markdown, inline hf-example blocks, and updated internal /docs/... links. Legacy docs/guide/*.md VuePress sources (including ::: example / @[code] blocks) are removed from that tree. scripts/generate-content.mjs now mainly normalizes TypeDoc output into src/content/docs/api/ and writes public/_redirects for legacy .html URLs. Root .eslintignore ignores the whole docs/ package.

Site UX: astro.config.mjs wires Rapide theme, sitemap, expressive code plugins, custom Header/Footer/Head/ThemeSelect, and starlight-page-actions with PageTitle/PageSidebar overrides so Copy Markdown / ChatGPT / Claude actions sit in the right sidebar. test-build.mjs adds post-build checks (link integrity, VuePress token leaks, examples, Pagefind).

Governance: Adds CLAUDE.md / AGENTS.md, README-EDITING.md, README-DEPLOYMENT.md, and rewrites docs/README.md for the new workflow (npm run dev in docs/, docs:build from repo root). Removes the old VuePress api-ref-readme.md template.

Reviewed by Cursor Bugbot for commit 0509e26. Bugbot is set up for automated code reviews on this repo. Configure here.

GreenFlux added 3 commits May 28, 2026 11:27
Replaces the VuePress 1.x docs site with Astro 6 + Starlight 0.38. The
previous `docs/.vuepress/` configuration stays in place for now since
it's no longer wired into the build pipeline -- a separate cleanup will
remove it.

Migration highlights:

- `docs/astro.config.mjs` configures Starlight with the Rapide theme,
  Expressive Code (line numbers + collapsible sections), a sitemap,
  and `starlight-page-actions` (Copy Markdown + Open in ChatGPT /
  Claude buttons on every page).
- Guide pages, the homepage, and the 404 move from the legacy
  `docs/guide/*.md` + `docs/index.md` tree into `src/content/docs/`
  and are tracked in git. They were run through the VuePress preprocessor
  once at migration time, so they now contain Starlight-native asides
  (`:::tip[Title]`), HTML `<details>` accordions, fully resolved
  `@[code]` includes, and rewritten links with the `/docs` base prefix.
- The TypeDoc-generated API reference is the only path that still
  passes through `scripts/generate-content.mjs` -- it normalizes
  TypeDoc's link forms and badge tokens.
- The Netlify `_redirects` file (legacy `.html` URLs → clean URLs) is
  also generated by `generate-content.mjs`, now derived from the
  tracked content under `src/content/docs/guide/`.
- Custom Starlight component overrides for `Head`, `Header`, `Footer`,
  and `ThemeSelect` reproduce the Handsontable docs look-and-feel
  (two-row header, sun/moon theme toggle, spreadsheet-style footer).
- Root build orchestration (`docs:build` script chain, Netlify build
  command, GitHub Actions `build-docs.yml`) updated to invoke the
  Astro build via `npm ci && npm run build` inside `docs/`.

Legacy `docs/guide/`, `docs/index.md`, and `docs/api-ref-readme.md`
are deleted -- their content lives under `src/content/docs/` now.
Introduces four governance files under `docs/` so contributors -- and
AI coding agents -- have a clear, self-contained reference for how to
work on the docs site:

- `docs/CLAUDE.md`: authoring standards. Diátaxis page-type taxonomy
  with folder-to-type mapping, voice and style rules with a banned-word
  list, four page-structure templates (tutorial / how-to / reference /
  explanation), example-data domain conventions, code-example rules
  (language tags, `licenseKey: 'gpl-v3'`, builder methods), the
  frontmatter schema with permanent 8-char IDs and the
  `| HyperFormula` metaTitle suffix, link conventions, the Excel /
  Google Sheets trademark notice text, the sidebar registration step,
  the Starlight-native asides / live-runner HTML pattern, and a PR
  checklist.
- `docs/AGENTS.md`: symlink to `CLAUDE.md` so both naming conventions
  resolve to the same file.
- `docs/README-EDITING.md`: practical reference -- frontmatter long-form,
  Starlight aside examples, the live-runner HTML pattern with file
  layout, line highlighting in code blocks, and sidebar registration.
- `docs/README-DEPLOYMENT.md`: deployment reference -- Netlify build
  command, the `docs:build` pipeline (`bundle-all` →
  `typedoc:build-api` → `npm ci && npm run build`), GitHub Actions CI
  verification, and the auto-generated `_redirects` map.
The `starlight-page-actions` plugin defaults to rendering its action
row directly under the page heading. Match the Handsontable docs UI by
moving the actions (Copy Markdown, Open in ChatGPT, Open in Claude)
into the right-hand sidebar, below the "On this page" table of
contents.

Adds two Starlight component overrides:

- `PageTitle.astro`: renders only the default page title and drops the
  plugin's button row. The plugin's override is suppressed because user-
  configured overrides win over plugin-supplied ones in Starlight.
- `PageSidebar.astro`: renders the default TOC, then appends a flat
  action list styled to match the right-sidebar typography. The Copy
  Markdown handler reuses the plugin's `.md` companion routes and shows
  a transient checkmark on success.
@netlify
Copy link
Copy Markdown

netlify Bot commented May 28, 2026

Deploy Preview for hyperformula-dev-docs ready!

Name Link
🔨 Latest commit 0509e26
🔍 Latest deploy log https://app.netlify.com/projects/hyperformula-dev-docs/deploys/6a204a24e8d7dd000838a419
😎 Deploy Preview https://deploy-preview-1686--hyperformula-dev-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread docs/src/plugins/vuepress-preprocessor.mjs Fixed
CI flagged two issues on PR #1686:

- The `build-docs` GitHub Actions job and the Netlify deploy preview
  both failed because Astro 6 requires Node >=22.12.0, but every Node
  pin in the docs setup specified 20. Bump `.nvmrc`, the docs
  `engines.node` constraint, the `build-docs.yml` job matrix, the
  Netlify `NODE_VERSION`, and the "Node 20" mentions in the README /
  CLAUDE.md / README-DEPLOYMENT to 22 (22.12 for the engines pin).
- CodeQL flagged `cleanTitleText()` in `vuepress-preprocessor.mjs` for
  incomplete multi-character sanitization (`js/incomplete-multi-character-sanitization`).
  A single pass of `/<[^>]+>/g` could leave a `<script>` substring
  behind for inputs like `<sc<script>ript>`. Iterate the strip to a
  fixed point so nested tags collapse fully. The downstream consumer
  (Starlight rendering a YAML `title:`) already escapes HTML, so this
  is defence-in-depth, but the warning is correct in principle.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 28, 2026

Performance comparison of head (0509e26) vs base (79f2f15)

                                     testName |   base |   head | change
------------------------------------------------------------------------
                                      Sheet A | 495.96 | 485.53 | -2.10%
                                      Sheet B | 159.24 | 150.88 | -5.25%
                                      Sheet T |  143.1 | 136.95 | -4.30%
                                Column ranges | 472.73 | 459.56 | -2.79%
Sheet A:  change value, add/remove row/column |  14.78 |  14.44 | -2.30%
 Sheet B: change value, add/remove row/column | 122.32 | 121.15 | -0.96%
                   Column ranges - add column | 141.88 | 146.31 | +3.12%
                Column ranges - without batch | 429.25 | 450.38 | +4.92%
                        Column ranges - batch | 107.85 | 112.53 | +4.34%

GreenFlux added 3 commits May 28, 2026 12:19
The Netlify deploy preview for #1686 kept failing with
"Node.js v18.20.8 is not supported by Astro" even after setting
NODE_VERSION = "22" in netlify.toml's [build.environment]. The deploy
log showed Netlify resolving Node from the root .nvmrc ("v18") rather
than honoring the netlify.toml env var. Bump .nvmrc to 22 so both
sources agree.

The HyperFormula library is already exercised on Node 20/22/24 by
.github/workflows/build.yml, so bumping the local-dev default to 22 is
consistent with what CI already tests.
Astro builds the site with `base: '/docs'`, so generated HTML
references `/docs/_astro/*`, `/docs/guide/*`, etc. In production the
canonical URL `hyperformula.handsontable.com/docs/` is served by a
reverse proxy that strips the `/docs` prefix before forwarding to the
Netlify project, so the prefix in the HTML resolves to the right files.

Netlify deploy previews (and the netlify.app subdomain in general)
don't sit behind that proxy, so `/docs/`-prefixed paths 404 — only the
home page rendered, and even then without styles or images because
every `/docs/_astro/*` URL came back as a 404. Add a wildcard rewrite
to netlify.toml so the preview mimics the production proxy: any
`/docs/<path>` request is served from `<path>` in the publish directory.

The Astro-generated `_redirects` file is processed first (so the legacy
`.html` → clean URL redirects still match), then this catch-all
rewrites everything else.
The version pill in the docs header rendered as "v0.0.0" on the Netlify
deploy preview even though the same code returned the correct "3.3.0"
locally. The cause was the brittle `../../..` arithmetic used to find
the library root: in some build environments (apparently Astro's
build container on Netlify), `import.meta.url` resolves through a
location that's one directory deeper than expected, so three parent
hops landed inside `docs/` instead of at the repo root. That made the
fallback read `docs/package.json` (version `0.0.0`) instead of the
library's `package.json`.

Replace the path arithmetic with an upward walk that stops at the first
`package.json` whose `name` is `hyperformula`. This is robust to any
build-cache layout. While here, also fall back gracefully when the UMD
bundle exists but is missing individual fields.
@GreenFlux
Copy link
Copy Markdown
Contributor Author

@sequba @sl01k , this is still a draft, but it's getting close. Here's the latest DP if you want to have a look:
https://deploy-preview-1686--hyperformula-dev-docs.netlify.app/

GreenFlux added 3 commits June 1, 2026 13:40
The toolbar's horizontal divider was constructed from `border-top` on
each `.hf-nav__link` element, so it only rendered where the framed nav
tabs sat. To the left of the first tab and to the right of the Support
dropdown, the line broke off and left visible gaps.

Mirror Handsontable's `.header-row-2::before` pattern: add a single
full-viewport `::before` pseudo-element to `.hf-header__row--nav` so a
continuous 1px line stretches edge-to-edge. The per-tab top borders sit
at the same Y-coordinate and overlap the pseudo-element where tabs
exist; the pseudo-element bridges the gaps elsewhere. The active-tab
brand-blue frame and z-index stacking are unchanged.
Brings in `00e5c730a` "Clean up in-repo dev docs (HF-65) (#1682)" which
adds root-level `DEV_DOCS.md`, `AGENTS.md`, `.cursor/rules/main.mdc`,
and re-points root `CLAUDE.md` / `CONTRIBUTING.md` as symlinks. Those
files live at the repo root and govern library development, separate
from the docs-site governance files this PR adds under `docs/`
(`docs/CLAUDE.md`, `docs/AGENTS.md`, `docs/README-EDITING.md`,
`docs/README-DEPLOYMENT.md`).

Git's rename detection auto-applied develop's edits to
`docs/guide/building.md` to the migrated location at
`docs/src/content/docs/guide/building.md` — no conflicts.
…border

The continuous `::before` divider line was already in place, but two
layout issues remained:

1. The per-tab `border-top` sat ~0.5rem below `::before` because
   `.hf-header__row` (the shared row class) applies `padding: 0.5rem 1rem`
   and `align-items: center` to every row. That offset rendered as a
   doubled line where the tabs were.
2. Inside `header.header`, Starlight's `padding-block` reserved
   ~0.75rem of dead space below `.hf-header`, so the per-tab vertical
   borders and hover backgrounds stopped short of the visible
   `border-bottom: 1px solid hairline-shade` boundary.

Three targeted overrides — modeled on Handsontable's `.header-row-2`
layout:

- `.hf-header__row--nav` drops vertical padding, sets `align-items:
  stretch`, `gap: 0`, and `min-height: 0`. Nav links now sit flush
  against the row's top so their `border-top` overlaps `::before`
  perfectly (single line).
- `.hf-header` changes `grid-template-rows` from `auto auto` to
  `auto 1fr` so row 2 absorbs the remaining vertical track height
  rather than leaving it empty.
- `header.header` overrides Starlight's `padding-bottom` to `0` so
  `.hf-header__row--nav` reaches the header's actual bottom border.
  The per-tab vertical lines and hover backgrounds now extend the full
  height of the toolbar, matching Handsontable's design.
@GreenFlux GreenFlux marked this pull request as ready for review June 1, 2026 18:53
@GreenFlux GreenFlux requested review from qunabu and sequba June 1, 2026 18:53
@GreenFlux
Copy link
Copy Markdown
Contributor Author

Comment thread docs/astro.config.mjs
Starlight constructs the "Edit this page" URL by appending
`entry.filePath` (the source file path relative to the Astro project
root, which is `docs/`) to `editLink.baseUrl`. With the previous value
ending in `docs/content/`, the resulting URL would have been
`.../edit/develop/docs/content/src/content/docs/guide/<slug>.md` —
a path that does not exist in the repository.

The `docs/content/` suffix was carried over from Handsontable's
`astro.config.mjs`, where guides actually live at `docs/content/` via
a symlink. In HyperFormula the sources live directly at
`docs/src/content/docs/`, so the base needs to point at `docs/`.

No "Edit on GitHub" link is currently rendered (my Footer / PageTitle /
PageSidebar overrides don't include one, and `starlight-page-actions`
doesn't expose an edit action), so the misconfigured URL was latent.
This fix removes the trap before anyone adds the button back.
Comment thread docs/astro.config.mjs
Brings in two content-only commits that landed on develop after the
last sync:

- 0e047ee docs: fix SSR section framing in React integration guide (#1688)
- 79f2f15 docs: rewrite Vue integration guide around markRaw pattern (#1689)

Both touch files we migrated from `docs/guide/` to
`docs/src/content/docs/guide/`. Git's rename detection auto-applied
the develop-side edits to the new locations — no conflicts.

GitHub had flagged the PR as CONFLICTING because its mergeability check
hadn't recomputed since develop's last push; pushing this merge clears
that flag.
Comment thread docs/src/components/PageSidebar.astro
cursoragent and others added 2 commits June 3, 2026 14:58
Co-authored-by: GreenFlux <GreenFlux@users.noreply.github.com>
Caught by Cursor Bugbot on PR #1686.

`astro.config.mjs` gates the Google Tag Manager snippet on
`process.env.BUILD_MODE === 'production'`, but nothing in the Netlify
config or the GitHub Actions docs-build workflow was setting the
variable — so the production deploy of the docs site would silently
ship without GTM, dropping analytics that the previous VuePress site
had always loaded.

Setting `BUILD_MODE = "production"` under
`[context.production.environment]` is the right Netlify-native pattern:
it only applies to deploys from the production branch, leaving PR
deploy previews and branch deploys with `BUILD_MODE` unset so analytics
doesn't fire on non-canonical URLs.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0509e26. Configure here.

Comment thread docs/AGENTS.md
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.16%. Comparing base (79f2f15) to head (0509e26).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1686   +/-   ##
========================================
  Coverage    97.16%   97.16%           
========================================
  Files          176      176           
  Lines        15322    15322           
  Branches      3356     3356           
========================================
  Hits         14887    14887           
  Misses         427      427           
  Partials         8        8           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@GreenFlux
Copy link
Copy Markdown
Contributor Author

@sequba ready for review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants