Skip to content

fix(website): repair docs frontmatter handling, then use it for SERP descriptions - #827

Merged
blove merged 1 commit into
mainfrom
blove/docs-frontmatter-description-fix
Aug 24, 2026
Merged

fix(website): repair docs frontmatter handling, then use it for SERP descriptions#827
blove merged 1 commit into
mainfrom
blove/docs-frontmatter-description-fix

Conversation

@blove

@blove blove commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #826. Started as "apply three meta descriptions"; checking whether the mechanism worked first turned up two live bugs that would have silently swallowed the change.

Two regressions that hid each other

The frontmatter description was never read. FRONTMATTER_DESCRIPTION_PATTERN spliced both fences into a single match and required a key to follow description:. description: is the last key in every frontmatter block in content/docs/, so it never matched and every such page fell back to its first paragraph.

The frontmatter rendered as Markdown. Because the description was ignored, the only visible symptom was this: the docs route passed raw file contents to next-mdx-remote, which doesn't strip frontmatter unless asked. Markdown read the block as an <hr> plus a setext <h2>:

<h2 id="title-custom-catalogsdescription-compose-custom-component-catalogs-…">
  title: Custom Catalogs description: Compose custom component catalogs…
</h2>
<h1 id="custom-catalogs">Custom Catalogs</h1>

A junk heading above the real <h1>, in the page, its TOC, and its heading-anchor aria-label. Live in production on /docs/chat/guides/custom-catalogs and /docs/render/api/views.

/docs/choosing-an-adapter was the one unaffected page — it carried its own private stripFrontmatter. That copy is now deleted in favour of the shared one.

The fix

Match the block, then search it for keys. Strip it through a shared stripFrontmatter. ResolvedDoc gains an explicit body — the description is read from content, so stripping in place would have traded one bug for the other.

Then the actual CTR work

Derived descriptions truncate at 180 chars; Google cuts at ~155. /docs/langgraph/api/inject-agent101 impressions at position 5.6, the top striking-distance page in the first GSC pull — was serving a snippet ending mid-word:

injectAgent() is the LangGraph adapter for Angular. It connects to a LangGraph Platform assistant, consumes the LangGraph SDK event stream, and projects th**…**

Three descriptions set, all under 155, each answering the query instead of restating the title. resolveDocDescription is shared with the JSON-LD, so the meta tag and structured data stay in sync automatically.

Deliberately not touched: ag ui angular and json-render vs a2ui. At n=8..25, hyphen/space twins of the same query swing 0% → 25% at identical position — binomial noise, not a CTR signal.

Verification

  • npx vitest run --config vite.config.mts from apps/website: 312 passed, 5 failed
    • The 5 are pre-existing in thanks/page.spec.tsx, PostCard.spec.tsx, Differentiator.spec.tsx — none touched by this diff. 307 passed before; the 5 added tests account for the delta.
  • nx lint website: 0 errors, 29 warnings (unchanged)
  • nx build website --configuration=production: succeeds
  • Built HTML in dist/ confirms all four affected pages carry the intended <meta name="description"> and zero <h2 id="title-…">

🤖 Generated with Claude Code

…RP descriptions

Two regressions that hid each other. `FRONTMATTER_DESCRIPTION_PATTERN` spliced
the opening and closing fences into one match and required a key to *follow*
`description:`, so the last key in a block never matched — and `description:` is
the last key in every frontmatter block in content/docs/. Every such page
silently fell back to its first paragraph.

Because the description was ignored, the only visible symptom was the second
bug: the docs route handed raw file contents to `next-mdx-remote`, which does
not strip frontmatter unless asked. Markdown then read the block as an `<hr>`
followed by a setext `<h2>`, putting a junk "title: … description: …" heading
above the real `<h1>` on /docs/chat/guides/custom-catalogs and
/docs/render/api/views — in the page, its table of contents, and its heading
anchor labels. Live in production since the frontmatter was added.

Match the block first and search it for keys; strip it via a shared
`stripFrontmatter` (the one route that was already correct,
/docs/choosing-an-adapter, had its own private copy — now deleted). `ResolvedDoc`
gains an explicit `body`: the description is read from `content`, so stripping
in place would have traded one bug for the other.

With frontmatter working, set descriptions on the three pages the Search Console
data singles out. Derived descriptions truncate at 180 chars and Google cuts at
~155, so /docs/langgraph/api/inject-agent — 101 impressions at position 5.6, the
site's top striking-distance page — was serving a snippet that ended mid-word.
All three replacements are under 155 and answer the query rather than restating
the title. `resolveDocDescription` is shared with the JSON-LD, so the meta tag
and the structured data stay in sync.

Not touched: `ag ui angular` and `json-render vs a2ui` reads at n=8..25, where
hyphen/space twins of one query swing 0%->25% at the same position. That is
binomial noise, not a CTR signal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
threadplane Ready Ready Preview Aug 24, 2026 3:43pm

Request Review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@blove
blove merged commit ac1d588 into main Aug 24, 2026
28 checks passed
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