Fix TechArticle schema headline leaking competitor name on /docs/iac/comparisons/ - #20580
Conversation
… pages The TechArticle collector used Hugo's .Title for the JSON-LD headline field, which on /docs/iac/comparisons/ pages is the short left-nav label (e.g. "Terraform", "OpenTofu", "AWS CDK") rather than the page's actual subject. Every comparison page already declares the correct SEO title via title_tag (the same field head.html uses for the <title> tag), so prefer it with the same or-fallback pattern already used in schema/collectors/faq-entity.html. This affects all 19 URLs under /docs/iac/comparisons/, which are among Pulumi's most AI-cited and highest-traffic docs pages.
|
@claude #new-review |
Pre-merge Review — Last updated 2026-07-30T12:19:57ZTip Summary: This is a one-line fix to the Review confidence:
Investigation log
🔍 Verification trail
🚨 Outstanding in this PRNo outstanding findings in this PR.
|
|
Your site preview for commit 366b7f0 is ready! 🎉 http://www-testing-pulumi-docs-origin-pr-20580-366b7f01.s3-website.us-west-2.amazonaws.com |
Lighthouse Performance ReportCommit: 366b7f0 | Metric definitions
|
The defect
Every Pulumi-vs-competitor page under
/docs/iac/comparisons/publishes aTechArticleJSON-LD entity whose schema.orgheadlineis the competitor's bare name, because the collector used Hugo's.Title(the short left-nav sidebar label) instead of the page's real SEO title. Verified on production before this fix:<title>(correct)headline(wrong, before this PR)/docs/iac/comparisons/terraform//docs/iac/comparisons/opentofu//docs/iac/comparisons/aws-cdk//docs/iac/comparisons/crossplane//docs/iac/comparisons/cloudformation//docs/iac/comparisons/The counter-example that pointed straight at
.Titleleakage:/docs/iac/comparisons/terraform/opentofu/already had a correct headline ("OpenTofu vs. Terraform") only because its.Titlehappens to equal the full phrase. Every other comparison page's.Titleis just the short menu label, so its headline came out wrong.Why this matters
This is on the pages that carry the most weight for Pulumi's AI visibility. Per Profound (category "Infrastructure as Code", trailing 30 days), pulumi.com is the #1 cited domain in the category, and the comparison docs are individually among the most-cited
/docs/pages (terraform, opentofu, terraform vs opentofu, crossplane, aws-cdk, cloudformation together account for the large majority of/docs/citations in that window). GA4 shows/docs/iac/comparisons/terraform/as the #1 non-homepage organic landing page over the same window, with real sessions arriving from chatgpt.com and gemini.google.com. Structured data that mislabels these pages as being about the competitor works against exactly the queries ("pulumi vs terraform," "terraform alternatives," "cdk vs terraform") these pages are built to win.The fix
Every comparison page already declares the correct, Pulumi-first SEO title via front-matter
title_tag— the same fieldhead.htmlalready uses to render the actual<title>tag. This PR makes theTechArticleschema collector prefer it:This mirrors the fallback pattern already established in
schema/collectors/faq-entity.html("name" (or .Params.title_tag .Title)), so it's consistent with existing precedent in this codebase rather than a new pattern.Scope: one line changed in
layouts/partials/schema/collectors/article-entity.html. No visible copy,<title>, H1, ornamefield changes — this is schema-only.Verification
/docs/iac/comparisons/: every one has atitle_tagset, all under ~90 characters, none polluted with a| Pulumi...suffix or keyword stuffing — the fallback resolves cleanly everywhere in this section.title_tagset, behavior is unchanged (falls through to.Titleexactly as before) — this is additive, not a behavior change outside the affected pages.speakable/isPartOfgaps on this collector after finding an inline comment explainingspeakablewas intentionally removed as not applicable to developer tools — kept this PR to the one verified correctness defect rather than bundling in a judgment call.🧠 This PR was created by workprentice on behalf of the Pulumi SEO/AEO agent's operator.