feat(docs): site health + AI-citation fixes (A1, A2, A8 …) - #897
feat(docs): site health + AI-citation fixes (A1, A2, A8 …)#897dhananjay6561 wants to merge 26 commits into
Conversation
DocItem computed socialImage but never included it in the Article/ TechArticle JSON-LD, so every doc page emitted an Article without the required 'image' field -> ~146 pages flagged invalid structured data. Add image to articleSchema, falling back to the site-wide default social card (the same 1200x630 og:image from docusaurus.config.js) when a doc sets no front-matter image. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
The swizzled DocItem set <title>{title}</title>, identical to the on-page
<h1> (also the doc title) -> SEMrush 'Duplicate content in h1 and title'
on 124 pages. Append ' | Keploy Docs' so the title differs from the h1.
Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
13 images across 8 doc pages (glossary GIFs + running-keploy screenshots) had no alt attribute -> SEMrush 'Missing ALT' + weaker AI/accessibility extraction. Add descriptive alt to each. utg-vscode-extension from the audit list no longer exists on main, so it is not included. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Pre-existing whitespace/list-indent/final-newline issues in these two files (unrelated to the alt fix) would fail the prettier CI check once the files are touched. Apply prettier so the PR is clean. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
There was a problem hiding this comment.
Pull request overview
Updates the Docusaurus DocItem theme component to address SEO / AI-citation audit findings by improving structured data completeness and avoiding duplicate <title>/<h1> signals across docs pages.
Changes:
- Adds an
imagefield to the per-page Article/TechArticle JSON-LD (with a fallback when front matter has no image). - Appends a suffix to
<title>to differentiate it from the on-page<h1>.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Wrap the long articleImage fallback line and flatten the pre-existing nested-ternary indentation so the swizzled DocItem is clean under the CI-pinned prettier 2.8.8 (--check runs on changed files). Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
The prettify_code workflow pins prettier_version 2.8.8, but creyD/ prettier_action's npx step actually installs and runs prettier 3.9.6. 3.x changed nested-ternary indentation, so the prior 2.8.8-flattened schemaType ternary failed CI. Reformat to 3.9.6 (the version CI runs) so --check passes; all other changed files are already 3.9.6-clean. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Every /docs page emitted a generic Article. Route API-reference pages (api-testing-*, public-api, cli-commands, sdk-installation — by tag or path) to APIReference, and default all other docs to TechArticle. Both are Article subtypes accepting the same properties as articleSchema, so the schema shape is unchanged — just a precise, AI/Google-friendly type. Built HTML: 35 APIReference, 343 TechArticle, 0 generic Article from docs. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
general-glossary + 3 glossary terms shared one boilerplate description; share-tests copied the generate-api-tests description; k8s-proxy had a wrong (NextJS/Drizzle) description. Give each a unique, accurate one to clear SEMrush 'Duplicate meta descriptions'. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Pre-existing leading-space paragraphs (unrelated to the description change) would fail the prettier CI check once the file is touched. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
/leadership, /security and /privacy-policy emitted zero page-level schema. Add JSON-LD: leadership -> CollectionPage + ItemList of Person (name, photo, Twitter, worksFor Keploy); security -> WebPage + security ContactPoint (responsible-disclosure email); privacy-policy -> DigitalDocument with dateModified. Verified in built HTML. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
New dependency-free remark plugin extracts each ### question + following answer prose from FAQ docs (keploy-explained/*-faq) and injects FAQPage JSON-LD with Question/acceptedAnswer pairs, so they're eligible for FAQ rich results and AI extraction. Built HTML: FAQPage with 14/11/12 Q&A on the three FAQ pages. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Every route emitted several disconnected Organization nodes: the site-wide one plus copies inlined as SoftwareApplication.publisher, Article.author and Article.publisher, which had drifted to two different logo URLs. Declare each site-wide entity (Organization, WebSite, SoftwareApplication) once in src/schema/siteEntities.js with a stable @id and reference it by @id everywhere else, so consumers merge them into a single entity per page. - docusaurus.config.js: three sibling ld+json blocks -> one @graph (siteGraph) - DocItem: author/publisher/isPartOf reference the shared @ids; derive the Article @id from the trailing-slash canonical URL so it matches the URLs the glossary hub and bespoke pages emit; add a DefinedTerm on glossary term pages, keyed to the hub's DefinedTermSet @id (latest version only) - bespoke pages: about -> AboutPage, index -> CollectionPage + ItemList (off GetStartedPaths' exported data), leadership -> CollectionPage of Person, privacy-policy -> DigitalDocument, security -> WebPage + Organization contactPoint on the shared Org @id - glossary hub DefinedTerms gain the same @id as their term pages so the two listings resolve to one entity - GlossaryCard uses Docusaurus Link (build-checked, trailingSlash-aware) - scripts/verify-schema-graph.js: fail CI on invalid JSON-LD or dangling @id Verified: clean build, verify-schema-graph reports 0 invalid / 0 dangling across 479 pages / 972 blocks; no generic Article remains. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
- samples-echo: two body sections used a single `#`, producing three h1s on the page (title + two). Demote both to `##` so the page has one h1 and a clean heading hierarchy (A8, multiple-h1). - configuration-file: rewrite four in-body doc links from http:// to https:// (the two remaining http:// occurrences are regex examples in a code block and are left as-is) (A9, HTTP-link-on-HTTPS-site). - api-testing-auth-setup: the title "Auth Setup" was flagged as too short and its description was a near-duplicate stub; give it a descriptive title and a unique description (sidebar_label stays "Auth Setup") (A9, title-too-short). Verified: clean build (onBrokenLinks: throw), verify-schema-graph 0 invalid / 0 dangling. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
…inks integrations-pr-agent was ~120 words (flagged "low word count"). Add a "What the PR Agent does" section and a Related block linking the AI test generator, UTG PR agent, and CI/CD GitHub setup, so the page carries real content and more than one internal link (A4). Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
…d links windows-wsl was ~177 words. Add why-WSL context, a Prerequisites section, clearer install steps, and a Related block (macOS/Linux install, CLI reference, common errors) to fix the thin-content and single-internal-link flags (A5/A4). Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Glossary term pages each had only one internal link (SEMrush "pages with only one internal link"). Add a "Related Terms" section to every term page linking 3–4 conceptually related terms plus the glossary hub, so terms form a connected cluster that both readers and AI engines can traverse. Link targets use each term's real route slug (e.g. agile-testing.md serves at /agile-unit-testing/, grey-box-testing.md at /gray-box-testing/), verified by a clean build under onBrokenLinks: throw. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
dhananjay6561
left a comment
There was a problem hiding this comment.
Code review — feat/ai-citation-health (PR #897)
Reviewed following the four-phase process. This is a large but well-structured PR (+1075/−263, 61 files); the bulk is low-risk template/frontmatter work, and the risky part — a site-wide @id-linked entity graph — is exactly the right architecture. Consolidating the four drifting Organization nodes into one siteEntities.js source of truth referenced by @id, driving GET_STARTED_PATHS from the same data the cards render, and the defensive link-filter in glossary.js are all strong calls. Build passes under onBrokenLinks: throw and the schema verifier reports 0 invalid / 0 dangling.
No blocking issues. I left inline notes: one 🟡 on the CI guard's dangling-@id detection (a real coverage gap, though it doesn't affect this PR's current bare-ref schema), one 🟡 on a URL-casing mismatch in the leadership schema, plus a 💡 on FAQ answer-text quality and a 🟢 on a self-contradicting comment. None need to block merge.
🎉 src/schema/siteEntities.js + the @id derivation from the trailing-slash canonical in DocItem is the standout — it fixes the actual root cause (fragmented, drifted entities) rather than papering over the symptoms, and the verify-schema-graph.js guard to keep it that way is the right instinct.
Add a "Related" section (3–4 contextual internal links) to running-keploy feature docs that had only one internal link. Links use each page real route slug, verified by a clean build under onBrokenLinks: throw. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Add a "Related" section to quickstart sample-app guides, linking same-language / same-datastore samples and the language recommendation page. Routes verified against the build (slugs differ from filenames here). Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Add a "Related" section to keploy-cloud pages that had a single internal link, linking sibling cloud features. Build-verified routes. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Add a "Related" section to keploy-explained pages, linking sibling concept/FAQ/setup docs. Build-verified routes. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Cross-link the GitHub, GitLab and Jenkins CI guides to each other and to the API-test CI/CD setup. Build-verified routes. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Add a "Related" section to the install pages and language SDK pages, cross-linking the SDKs and install guides. Build-verified routes. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Emit schema.org HowTo JSON-LD (visible={false}, no visual change) on the GitHub, GitLab and Jenkins
guides so AI engines can extract the install-and-run steps.
Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Emit HowTo JSON-LD (visible={false}) on the Go, Java, JavaScript and Python SDK pages covering
agent setup and coverage merge steps.
Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Emit HowTo JSON-LD (visible={false}) on the Linux, Windows and native Windows/WSL install pages.
Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Add gzip, Mux, Prisma, JWT, unbuggy, webhook, datastore, async, boolean, quickstarts and _Transform to the Vale accept vocabulary. These appear in the new "Related" link text and in prettier-normalized code lines, and are valid terms the Vale spell-check does not recognise. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
da86911 to
409fbff
Compare
Summary
Site Health + AI-citation / GEO overhaul for the docs site, from the Aug 2026 SEMrush audit (Site Health 84%, AI Search Health 84%) and the schema-type audit. Covers docs tickets A1–A10 / AI1–AI6 plus a full structured-data rework, prioritising template-level fixes that clear hundreds of pages at once.
📊 Ticket status
SEOAIimageon Article schema — fixes ~146 "invalid structured data"SEO<title>differentiated from on-page<h1>(124 pages)A11YAIaria-labelsSEOAISEOAISEOA11YSEOalton 13 images;samples-echotriple-h1 → single h1SEOhttp→httpsdoc links;auth-setuptitle-too-short + dup descriptionSEO1.0.0/2.0.0arenoIndex: true— intentionalSEOAIArticle→TechArticle+APIReference(0 generic Article remain)SEOAI@idgraphSEOAIDefinedTermon 37 glossary term pages, keyed to the hub'sDefinedTermSet@idSEOAI/(CollectionPage+ItemList),/about(AboutPage),/leadership(CollectionPage+Person),/security(WebPage+ContactPoint),/privacy-policy(DigitalDocument)SEOscripts/verify-schema-graph.jsfails on invalid JSON-LD / dangling@idAIFAQPageJSON-LD on the 3 FAQ docsAIHowToJSON-LD (visible={false}) on 10 more step-by-step guides (CI/CD, SDK install, Linux/Windows install) — 44 HowTo pages totalSEOAInoIndex/ commented components — no rich-result payoffPERF✅ Changes (highlights)
Structured data — one
@id-linked entity graphOrganizationnodes (site-wide +SoftwareApplication.publisher+Article.author+Article.publisher), drifted to two logo URLs. Now declared once insrc/schema/siteEntities.jswith a stable@idand referenced by@ideverywhere.docusaurus.config.js: threeld+jsonblocks → one@graph.DocItemreferences the shared@ids; Article@idderives from the trailing-slash canonical URL so it matches other emitters. AddedDefinedTermon glossary term pages.scripts/verify-schema-graph.js— CI guard against invalid JSON-LD / dangling@id.Structured data — specialization & bespoke pages
APIReference, all other docs →TechArticle; 0 genericArticle.imageon the Article schema (was computed but never emitted → ~146 "invalid").CollectionPage/ItemList/AboutPage/WebPage+ContactPoint/DigitalDocument, all@id-linked to the site graph.AI-citation / GEO
visible={false}HowTo on the CI/CD, SDK-install and OS-install guides (schema only, no visual change).SEO / a11y
samples-echosingle-h1; A9httpslinks + descriptiveauth-setuptitle.🧭 Notes / deviations
noIndexcomponents; emitting them adds schema with no citation/rich-result payoff.AggregateRating/Reviewviolates Google policy; real ratings stay via OrganizationsameAs(G2/Gartner/Capterra). (Same call as perf(docs): core web vitals — self-host fonts, drop dead assets, defer pixel, add security headers #896.)✅ Verification
npm run buildsucceeds (onBrokenLinks: throw); changed files pass prettier 3.9.6.node scripts/verify-schema-graph.js build(served versions; skipsnoIndex1.0.0/2.0.0): 479 pages, 982 JSON-LD blocks, 0 invalid, 0 dangling.@typedistribution includesTechArticle174,HowTo44,DefinedTerm37,APIReference31,FAQPage3,CollectionPage2,AboutPage/DigitalDocument/WebPage/DefinedTermSet1 each, and 0 genericArticle(all-versions counts are higher; 1.0.0/2.0.0 keep their own copies).