fix(schema): mirror title_tag instead of sidebar .Title in JSON-LD names - #20630
Conversation
…names WebPage.name, HowTo.name, CollectionPage.name/ItemList children, and the tutorials Course/ItemList names were all built from Hugo's .Title, which is the SHORT left-nav sidebar label, not the real page title. head.html already builds the actual <title> tag from title_tag when present (falling back to .Title) — this brings the schema graph in line with that same precedence so the structured data matches what the browser tab and search snippet actually show. 668 content files declare title_tag. Before this fix those pages collapsed to only 584 distinct WebPage.name values (133 pages emitting a name duplicated elsewhere); after, 667 of 668 are distinct. Changed: - layouts/partials/schema/graph-builder.html: WebPage.name - layouts/partials/schema/collectors/howto-entity.html: HowTo.name and its description fallback - layouts/partials/schema/collectors/collection-entity.html: CollectionPage.name and the child ListItem.name in its ItemList - layouts/partials/schema/content/course-list.html: Course.name (per tutorial listed) and the tutorials-hub ItemList.name Deliberately left unchanged (documented in PR body): blog-entity.html headline, video-entity.html (zero exposure), product-entity.html (conflicts with open PR #20552).
Pre-merge Review — Last updated 2026-08-03T22:54:35ZTip Summary: This is a Hugo template change, not content: four JSON-LD schema partials now build their Review confidence:
Investigation log
🔍 Verification trailNo prose claims were extracted from this diff (it changes Hugo templates only). These entries record the template checks that produced the findings below:
🚨 Outstanding in this PRNo outstanding findings in this PR.
|
|
Your site preview for commit 318d695 is ready! 🎉 http://www-testing-pulumi-docs-origin-pr-20630-318d6956.s3-website.us-west-2.amazonaws.com |
Lighthouse Performance ReportCommit: 318d695 | Metric definitions
|
|
@claude Implement the suggested low-confidence findings and #update-review |
…ow comment Addresses low-confidence review findings: the meta_desc/description printf fallbacks in howto-entity.html and course-list.html now interpolate .Title (the short page title) rather than the title_tag-preferring name, avoiding broken sentences when title_tag is phrased as a full sentence or question. Also narrows graph-builder.html's new comment, since head.html's title precedence isn't quite what it described (blog term/category/series overrides, and a site-name suffix). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
🤖 Review updated on @CamSoper's request. |
Summary
Technical SEO fix: JSON-LD schema fields that are supposed to carry the real page title (
WebPage.name,HowTo.name,CollectionPage.name, tutorialCourse.name/ItemList.name) were built from Hugo's.Title, which is the short left-nav sidebar label, not the actual page title.layouts/partials/head.html(lines 279–281) already sets the real<title>tag from.Params.title_tagwhen present, falling back to.Title— this PR mirrors that same precedence in the schema graph so structured data matches what the browser tab and search snippet actually show.This is the third and final instance of a recurring bug class this week:
SoftwareApplication.name(PR #20535/#20552 line of work) andTechArticle.headline(PR #20580) both had the identicaltitle_tagvs.Titleconfusion. This PR closes the class by sweeping every schema collector for the same leak.Why it matters
title_tag:. Before this fix, every one of those pages emitted the sidebar label (not the real title) intoWebPage.name.WebPage.namevalues — 133 pages carried a name duplicated at least once elsewhere on the site. Worst offenders: "Azure" ×5, "AWS" ×5, "Operations" ×4, "Next steps" ×4, "Install Pulumi" ×4, "Google Cloud" ×4, "Terraform" ×3, "Kubernetes" ×3.content/docs/iac/comparisons/cloudformation.md— a Pulumi comparison page was graph-named after the competitor ("AWS CloudFormation" instead of "Pulumi vs. AWS CloudFormation").content/docs/iac/comparisons/_index.mdandcontent/docs/esc/vs/_index.mdboth emitted the identicalWebPage.name"Comparisons" — two different hub pages, indistinguishable in the graph.content/tutorials/glossary/aws-eks.md— "Elastic Kubernetes Service" instead of "What is AWS Elastic Kubernetes Service (EKS)?" — glossary pages are prime AEO assets and were losing the question framing LLMs pattern-match on.create-project.mdpages across aws/azure/gcp/kubernetes get-started tracks were indistinguishable by name.Changes
All follow the existing
(or .Params.title_tag .Title)guard pattern already used in this codebase (article-entity.html,faq-entity.html,breadcrumb-entity.html,itemlist-entity.html):layouts/partials/schema/graph-builder.html—WebPage.name(the primary, highest blast-radius fix — every one of the 668 pages goes through this).layouts/partials/schema/collectors/howto-entity.html—HowTo.name, plus the description fallback that referenced the unguarded title.layouts/partials/schema/collectors/collection-entity.html—CollectionPage.name, plus the childListItem.namein its embeddedItemList(hub pages listing other pages).layouts/partials/schema/content/course-list.html— tutorialCourse.name(per listed tutorial) and the tutorials-hubItemList.name, plus the description fallback. Found during the sweep; not in the original three known offenders but the identical bug.Deliberately left unchanged
collectors/blog-entity.htmlBlogPosting.headline(.Title) — only 4 blog posts havetitle_tag, and in all 4,.Titleis the genuine article headline/h1 whiletitle_tagis a plain-text SEO variant (e.g. "Pulumi 💜's Open Source" vs "Pulumi Loves Open Source").headlineshould mirror the h1, not the<title>tag — divergence there is correct semantics, not a bug.collectors/video-entity.html— zero video pages currently declaretitle_tag, so there's no live exposure; left alone to avoid pointless churn.collectors/product-entity.html$productName := .Title— intentionally not touched. Open PR Add real Offer/AggregateOffer pricing schema to /pricing/ #20552 (seo/pricing-offer-schema) already modifies this exact file; editing it here would create a merge conflict. Follow-up in a future PR once Add real Offer/AggregateOffer pricing schema to /pricing/ #20552 lands.collectors/main-entity.html— uses.Titleonly for FAQ page detection (string match against the title), never emits it into schema. No action needed.utils/content-aggregator.html— uses.Titleonly as content-analysis input for word-count estimation, never emitted as a schemaname. No action needed.article-entity.html,faq-entity.html,breadcrumb-entity.html,itemlist-entity.html,event-entity.html.Verification
{{vs}}) checked on every edited file against the pre-edit baseline — each edit added exactly one balanced pair, no pre-existing imbalance introduced by this change (one file,howto-entity.html, has a pre-existing 1-delimiter mismatch unrelated to this edit, present before and after at the same offset).hugo --renderToMemoryrun fails on an unrelated pre-existing environment gap (missing generated OpenAPI spec / CSS asset pipeline), not a regression from this change.This PR was created by workprentice on behalf of the Pulumi SEO/AEO content team — no
get_me-equivalent tool was available in this session to resolve a specific requester's username.