Skip to content

fix(seo): remove @type from JSON-LD stub references on plugin pages#4763

Draft
vfanucci wants to merge 1 commit intomainfrom
fix/schema-stub-references
Draft

fix(seo): remove @type from JSON-LD stub references on plugin pages#4763
vfanucci wants to merge 1 commit intomainfrom
fix/schema-stub-references

Conversation

@vfanucci
Copy link
Copy Markdown
Contributor

@vfanucci vfanucci commented May 8, 2026

Summary

Google Rich Results test flagged the `SoftwareApplication` schema as invalid on plugin task pages (e.g. `/plugins/plugin-jdbc-vectorwise/io.kestra.plugin.jdbc.vectorwise.batch`) with two critical errors:

  • Missing `name` field
  • At least 2 of `offers`, `aggregateRating`, `applicationCategory`, `operatingSystem` required

Root cause

In `TechArticle.about` on task pages, the `SoftwareApplication` was referenced as a stub:

```json
"about": {
"@type": "SoftwareApplication",
"@id": "https://kestra.io/plugins/plugin-jdbc-vectorwise#plugin-jdbc-vectorwise"
}
```

Google's validator treats every node with `@type` as an independent entity to validate, even when it's a cross-page reference. It doesn't follow the `@id` to find the canonical definition on the parent plugin page.

Fix

Drop `@type` from pure `@id` references — treat them as pointers, not new declarations. The full `SoftwareApplication` definition on `/plugins/` (with all required fields) remains untouched and serves as the source of truth.

Same pattern applied to:

  • `TechArticle.about` on task pages → `SoftwareApplication` ref
  • `TechArticle.isPartOf` on task pages → `WebSite` ref
  • `SoftwareApplication.isPartOf` on parent plugin pages → `#software` ref
  • `CollectionPage.about` on plugins index → `#software` ref

Test plan

  • Deploy to preview and re-test on Google Rich Results (URL needs to be updated to preview domain)
  • Verify the canonical `SoftwareApplication` on `/plugins/` parent pages still validates with all required fields
  • Spot-check a few task pages render JSON-LD without `@type` in the `about`/`isPartOf` stubs

🤖 Generated with Claude Code

Google Rich Results validates every node with @type as an independent
entity, even when it's a cross-page reference via @id. On plugin task
pages, this caused the SoftwareApplication stub in TechArticle.about to
fail validation (missing name, applicationCategory, etc.) despite the
canonical entity being correctly defined on the parent plugin page.

Drop @type from pure @id references so they're treated as pointers, not
new declarations. The canonical SoftwareApplication on /plugins/<name>
remains the source of truth.

Same pattern fixed on plugins index page (about: SoftwareApplication
stub) and the SoftwareApplication.isPartOf reference to #software.

Test: https://search.google.com/test/rich-results?url=https%3A%2F%2Fkestra.io%2Fplugins%2Fplugin-jdbc-vectorwise%2Fio.kestra.plugin.jdbc.vectorwise.batch

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

☁️ Cloudflare Worker Preview Deployed!

🔗 https://ks-fix-schema-stub-references-docs.kestra-io.workers.dev
🔗 https://15cf6114-docs.kestra-io.workers.dev

## 🔦 Lighthouse Benchmark

Tested: https://ks-fix-schema-stub-references-docs.kestra-io.workers.dev on 2026-05-08 15:41 UTC
Compared against main baseline from 2026-04-10

Scores (0–100, higher is better)

Page Performance Accessibility Best Practices SEO
Home 70 🟢 +13 82 59 92
Pricing 94 91 59 100
Enterprise 95 🟢 +11 82 59 100
Cloud 88 86 59 100
About Us 81 🔻 -14 91 59 100
Docs Landing 86 88 59 92
Contribute to Kestra (simple docs) 92 87 59 92
Flow (full featured docs) 86 90 59 92
Blog Index 66 🔻 -15 90 59 100
Blog Post (sample) 86 🔻 -11 87 59 100
VS Page (sample) 95 91 59 100
Plugins Landing 88 80 59 92
Plugin Page (sample) 95 87 59 100
Plugin Debug Page (sample) 94 87 59 100
Plugin Debug Return Page (sample) 93 87 59 100
Blueprints Landing 88 80 59 92
Blueprint Audit Logs CSV Export 55 86 59 100

Core Web Vitals (lower is better)

Page LCP FCP TBT CLS Speed Index
Home 1.10 s 🟢 0.72 s 🟢 452 ms 🔻 0.002 3.14 s 🟢
Pricing 1.10 s 0.59 s 160 ms 🔻 0.000 0.85 s
Enterprise 1.15 s 🟢 0.61 s 🟢 133 ms 🔻 0.000 0.89 s 🟢
Cloud 2.11 s 0.58 s 107 ms 🔻 0.000 0.96 s
About Us 3.44 s 🔻 0.58 s 63 ms 0.000 0.88 s
Docs Landing 0.93 s 🟢 0.58 s 🟢 303 ms 🔻 0.000 0.94 s
Contribute to Kestra (simple docs) 1.00 s 0.61 s 202 ms 🔻 0.000 0.86 s
Flow (full featured docs) 1.07 s 0.52 s 🟢 277 ms 🔻 0.000 1.23 s
Blog Index 5.07 s 🔻 0.54 s 88 ms 🔻 0.000 22.34 s 🔻
Blog Post (sample) 2.47 s 🔻 0.54 s 112 ms 🔻 0.000 0.71 s 🟢
VS Page (sample) 1.03 s 0.57 s 148 ms 🔻 0.000 0.71 s 🟢
Plugins Landing 0.87 s 🟢 0.51 s 165 ms 🔻 0.000 2.84 s 🔻
Plugin Page (sample) 0.87 s 0.55 s 68 ms 🔻 0.051 1.89 s
Plugin Debug Page (sample) 0.84 s 0.54 s 117 ms 🔻 0.001 1.96 s 🔻
Plugin Debug Return Page (sample) 0.99 s 🟢 0.55 s 106 ms 🔻 0.025 2.08 s 🔻
Blueprints Landing 1.57 s 0.91 s 66 ms 0.000 2.28 s 🔻
Blueprint Audit Logs CSV Export 0.87 s 🟢 0.53 s 426 ms 🔻 0.485 2.21 s
Legend

🟢 improved  ·  🔻 regressed  ·  (blank) no significant change
Score threshold: ±10 pts  ·  Metric threshold: ±30% of baseline

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