Homepage Statistics & Version — Permanent Rule
Rule: homepage statistics and the displayed documentation version are never hardcoded. They are
recomputed from the actual docs/ tree and versions.json on every build. No developer should ever
hand-edit a homepage counter — if a number needs to change, add or remove the content that number counts,
and rebuild.
This was established during the Final UX/UI Production Polish pass, replacing a homepage that previously
hardcoded const CURRENT_VERSION = 'v1.2' and a fixed "4 frameworks published" badge — numbers that
would have silently gone stale the moment a new framework or version was added, exactly the kind of
maintenance burden this rule exists to prevent.
How It Works
plugins/portal-stats-plugin.cjs is a local Docusaurus plugin, registered in docusaurus.config.js's
plugins array. On every npm run build / npm run start, its loadContent() lifecycle:
- Counts published frameworks — subdirectories of
docs/frameworks/that have their own_category_.json(the marker that distinguishes a published framework from a draft "coming soon" placeholder, which ships only a bareindex.md). - Counts API endpoints — lines matching either documentation convention already in use across
framework guides: markdown table rows (
| GET | route |, used by E-Invoicing) and heading-style method declarations (## POST `RouteName`, used by Notification and WhatsApp Integration). Both are matched so the count stays accurate regardless of which convention a future framework's docs adopt. - Counts documentation pages — every
.md/.mdxfile underdocs/(the current, production version — not the frozenversioned_docs/snapshots). - Counts architecture documents — every
.md/.mdxfile underdocs/architecture/. - Reads the latest archived version —
versions.json[0], never a literal string in a component.
The computed object is exposed via actions.setGlobalData(content), and consumed on the homepage with:
import {usePluginData} from '@docusaurus/useGlobalData';
const {stats, latestArchivedVersion} = usePluginData('portal-stats-plugin');
src/components/PortalStats renders the four counters as KPI cards; src/pages/index.js reads
latestArchivedVersion for the version badge and the Latest Releases heading. Neither file contains a
literal number.
Adding a New Statistic
- Add a new counting function to
plugins/portal-stats-plugin.cjs(following the existing pattern — walk the filesystem, don't hand-count). - Add the new field to the object returned from
loadContent(). - Add a corresponding entry to the
itemsarray insrc/components/PortalStats/index.js. - Do not add a fallback hardcoded value "just in case" the plugin data is unavailable — if the plugin fails to load, that is a build error to fix, not a stale number to paper over.
Adding a New Framework or Doc Section
Nothing to do here — this is the entire point of the rule. Publish the framework under docs/frameworks/
with its own _category_.json (see any existing framework for the convention), and:
- Frameworks Published increments automatically.
- API Endpoints increments automatically, as long as the new framework's endpoint documentation uses either of the two conventions above (or a convention added to the plugin's regex).
- Documentation Pages increments automatically for every file added, anywhere under
docs/. - The homepage's Official Frameworks card grid (
src/components/HomepageFeatures) still needs its own card added manually — the stats plugin counts pages, it does not generate marketing card copy. That is a deliberate, separate concern: the count must never require a manual edit; the card describing a new framework is genuinely new content a human should write.
Cutting a New Documentation Version
See Documentation Versioning Strategy for the full release/archive
workflow. Relevant to this rule specifically: cutting a version only changes versions.json, which
latestArchivedVersion reads automatically — no homepage code changes are needed there either.
