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 30 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
A section index.md (e.g. /docs/concepts/) emitted a TechArticle despite being an index of child docs; it now emits a CollectionPage. Quickstart tutorial docs are additionally typed as LearningResource with learningResourceType so education-focused consumers and AI can classify them. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
…pment The /docs/application-development/ page emitted zero structured data. Add a WebPage, a BreadcrumbList, and an ItemList of the supported operating systems, keyed to the shared site entity graph. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
The community section rendered six official channels with no structured data. Emit an ItemList built from the same data the cards render, so search engines and AI can enumerate the channels. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
The home, about, glossary and application-development pages each hand-built the same Home -> Docs breadcrumb prefix, repeating the site/docs URLs and the ListItem position numbering. Add breadcrumbList(trail) to siteEntities (the existing schema source of truth); callers pass only the crumbs beyond Docs. Removes the now-unused SITE/HOME_URL constants; built breadcrumbs are unchanged. Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
f683b35 to
0295310
Compare
|
Note for reviewers — the failing
Resolution: split into smaller PRs (each scopes correctly) or bump/adjust the |
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).