Skip to content

docs: EN as root locale, SEO metadata, branding, footer, and prose in the API reference - #35

Merged
rasuvaeff merged 2 commits into
masterfrom
docs/en-root-seo-branding-footer-api-prose
Aug 5, 2026
Merged

docs: EN as root locale, SEO metadata, branding, footer, and prose in the API reference#35
rasuvaeff merged 2 commits into
masterfrom
docs/en-root-seo-branding-footer-api-prose

Conversation

@rasuvaeff

Copy link
Copy Markdown
Owner

Summary

Ports the same treatment applied to rasuvaeff/yii3-mcp's docs site to
property-testing's existing bilingual (EN/RU) VitePress site.

  • EN as root locale: docs/en/** moved to docs/** — English is now
    served at /, no more JS meta-refresh redirect hop. RU is unchanged
    (ru/ subdirectory + prefix). Every internal link, sidebar/nav config,
    and the three build scripts (aggregate.mjs, generate-api.mjs,
    check-integrity.mjs) updated for the new path scheme.
  • SEO: unique per-page title/description on all 146 pages (73 × 2
    languages) — README-section pages via a new description field in
    section-map.json (the generated .md can't be hand-edited, it's
    rebuilt every run), direct-imports (roadmap/migrating/llms) with
    language-specific text, hand-authored pages directly, and the 84
    generated API pages from each class's docblock summary. Per-page
    canonical + OG/Twitter via transformHead, sitemap.xml (146 URLs),
    robots.txt.
  • Branding: real logo (mark + full wordmark with the Testo-plugin
    badge) in navbar/hero/favicon. Custom .vitepress/theme adds a
    multi-column, locale-aware footer — labels and link prefixes switch
    on the current page's language via useData().
  • API reference: reflect-api.php now parses docblocks (summary +
    @param) instead of discarding them; generate-api.mjs renders class
    summaries as prose and methods as fenced ```php blocks. Shown on both
    locales (PHPDoc is English-only and translating it per-release isn't
    sustainable) — RU pages carry a one-line disclaimer instead of silently
    mixing languages.

Bugs found and fixed while building this

  • Two wrong #fragment anchors (CounterExample linked to a nonexistent
    /api/index#counterexample instead of its own class page) in
    intro/concepts.md and its RU mirror — caught by the new
    check-anchors.mjs (ported from yii3-mcp), which also verifies every
    internal href in the built HTML carries the site's base prefix.
  • The footer was rendering behind VPSidebar (position: fixed, above
    static content in the paint order for the whole page height) — fixed
    with position: relative + a higher z-index. Its grid used bare fr
    tracks (don't shrink below content min-width) — replaced with
    repeat(auto-fit, minmax(160px, 1fr)).

Test plan

  • npm run docs:build — aggregate → API generation → integrity check →
    VitePress build → anchor check, all green
  • 146/146 pages have a description: frontmatter (verified by script)
  • Verified visually via google-chrome --headless --screenshot
    (Claude in Chrome was declined this session): EN home at / with no
    redirect, logo in navbar/hero, footer on both EN and RU pages (fully
    visible, not hidden behind the sidebar, correct locale labels/links),
    <head> tags (title/description/canonical/favicon) on EN and RU
    pages, sitemap.xml with exactly 146 URLs

…e in the API reference

Same treatment as rasuvaeff/yii3-mcp's docs site, adapted for property-testing's
existing EN/RU bilingual structure (73 pages per language).

EN as root locale
- Moved docs/en/** to docs/** (English served at '/', no redirect hop) —
  docs/index.md was a JS meta-refresh redirect to /en/; it's now the real
  home page. Russian keeps its 'ru/' subdirectory and URL prefix, unchanged.
- Every internal link, the sidebar/nav config, aggregate.mjs, generate-api.mjs
  and check-integrity.mjs updated for the new path scheme.

SEO
- Unique per-page title/description on all 146 pages (73 per language): the
  16 README-section-derived pages get it via a new `description` field in
  section-map.json (rendered by aggregate.mjs — editing the generated .md
  directly would be overwritten on the next build); the 3 direct-imports
  (roadmap/migrating/llms) get language-specific text (RU's is a pointer-page
  note, since those sources have no RU sibling); the 12 truly hand-authored
  pages got it directly; the 84 generated API pages get it from each class's
  docblock summary (see below).
- Per-page canonical + Open Graph/Twitter meta via transformHead; sitemap.xml
  (built-in VitePress option, 146 URLs); robots.txt.

Branding
- Real logo assets (mark + full wordmark with the Testo-plugin badge) wired
  into the navbar, hero image (mark only, to avoid duplicating the hero's own
  text), and favicon.
- Custom .vitepress/theme (Layout.vue + Footer.vue) adds a multi-column,
  locale-aware footer (nav labels and link prefixes switch on the current
  page's language via useData()), matching the pattern on
  php-testo.github.io.

API reference
- reflect-api.php now parses each class's and method's docblock (summary +
  @param descriptions) instead of discarding it. generate-api.mjs renders
  the summary as prose and every method as a fenced ```php signature block
  (multi-line for long parameter lists) with its documented parameters below
  — on both locales, since PHPDoc prose is English-only and translating it
  per-release isn't sustainable; the RU pages carry a one-line disclaimer
  instead of silently mixing languages.

Fixes found while building this (both were verified live via
google-chrome --headless screenshots before/after, Claude in Chrome having
been declined this session)
- check-anchors.mjs (new, ported from yii3-mcp): two wrong #fragment
  anchors (CounterExample linked to a nonexistent /api/index#counterexample
  instead of its own class page) in both intro/concepts.md and its RU
  mirror; extended to also verify, post-build, that every internal href
  carries the site's base prefix.
- Footer.vue: VPSidebar is `position: fixed` with a z-index above static
  content for the entire page height, so an in-flow footer painted BEHIND
  it once scrolled that far — gave the footer `position: relative` + a
  higher z-index. Grid uses `repeat(auto-fit, minmax(160px, 1fr))` instead
  of fixed `fr` columns, which cannot overflow its container at any width.
Same treatment as yii3-mcp: default VitePress light mode keeps the page
canvas and cards at almost the same near-white, so nothing visibly
separates from the page. Scoped to :root:not(.dark) only — dark mode is
untouched, and this works purely through VitePress's own CSS custom
properties so it can never fight Shiki's light/dark token-color pairing.
Brand accent (teal) untouched.
@rasuvaeff
rasuvaeff merged commit 94cd449 into master Aug 5, 2026
9 checks passed
@rasuvaeff
rasuvaeff deleted the docs/en-root-seo-branding-footer-api-prose branch August 5, 2026 17:59
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.

1 participant