v4.24.0
Focus: page metadata moves into the Markdown itself — Quasar-docs compatible — and F5 after a redeploy stops breaking the page.
Changes
- 🧾 Added Markdown frontmatter metadata. A page may open with a Quasar-docs-style
---block (title,desc,keys,related, and any scalar registry config key). In-page metadata overrides the page's*.index.jsentry and merges in keys the registry doesn't have; localized keys (title,desc,keys) apply per locale — each.mdfile is one locale — andkeysappends to the sidebar search tags instead of replacing them.showcase/vsfiles may retitle their own subpage (reflected in that route's prerendered<title>/description, llms, MCP and AI Search titles). The block is metadata, never content: the rendered page, Table of Contents and search index are stripped, while the raw served.mdandllms-full.txtkeep it verbatim — so pages migrated from a Quasar docs project keep working and keep their metadata. - 🧩 The frontmatter overlay is collected from the markdown filename convention alone, so the Node registry loader and the generated
virtual:docsector-booksmodule (which receives pre-compiled patches plus a small applier) produce identical merges. Supported syntax is a documented YAML subset — scalars and one-level lists; unsupported lines warn at build time and are skipped. In dev, body edits keep instant HMR; only a change to the block itself restarts the registry. - 🛠️ Fixed the post-redeploy F5 breakage (
Failed to load module script… MIME type of "text/html"). Root cause chain: with no404.html, Cloudflare Pages served missing hashed assets as the SPA fallback — 200text/html— and the/assets/*immutable rule then cached that HTML under the asset URL for a year, while the old recovery script reloaded without cache-busting and permanently disarmed after one attempt. Now: the build emits a404.html(missing assets fail fast as real 404s; unknown page routes still render the app shell, with a semantically correct 404 status), document cache rules (must-revalidate) always ship even with Early Hints disabled, and the hardened inline recovery script verifies the live deploy viaversion.jsonbefore navigating once with a cache-busting query — offline-aware, bounded to two attempts per session, and inert after the app boots (post-boot chunk failures stay with the router-level recovery, which also gained the cache-busting query and a normalized loop guard). - 🐛 Fixed
definePage()silently dropping themetadatablock (search tags) — latent since the search-tags feature. - 🛡️ Hardened after an adversarial review confirmed 23 findings on the first cut — among them: the strip eating assistant answers that quote frontmatter (stripping is now page-scoped), two distinct reload-loop vectors in the recovery path, a shallow
subpageMetamerge that wiped registry locales, and a dev watcher that restarted the server on every save of unconventional markdown files. All fixed with dedicated regression tests. - 📚 Documented in the Pages and Routing guide (both locales, itself carrying a real frontmatter block as a live example), README, and the authoring skill.
- ✅ Validated with 401 passing tests (55 new) plus real-browser drills: a simulated deploy race self-heals in one cache-busted navigation with a clean final URL, and a permanently broken deploy stops after two attempts instead of looping.
Notes
- Behavior change: builds now emit
404.html. On Cloudflare Pages this turns unknown paths into real 404 statuses — the docs app shell still renders for unknown page routes (the client router shows its not-found view), and missing assets fail fast instead of being cached as HTML. Consumers relying on SPA-fallback 200s for client-only routes should note the status change. - Frontmatter
book/type, structural blocks (meta,data,metadata) and object-valued config keys (menu,subpages,link,layouts) cannot be set from frontmatter and warn at build time. - The recovery script assumes root-path deploys (
/version.json), matching every other engine-generated artifact.