mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-11 01:28:03 +00:00
## Summary This PR adds schema.org **JSON-LD structured data across the whole marketing site**, built from one shared, CMS-ready module and gated by a small CI validator. It replaces the old global block (which had a stale logo, wrong social links, disconnected nodes, and a head slot that rendered three times) with a single connected `@graph` on every page. Structured data only — there is no visual or runtime change for users. Tracks Linear **FE-1170**. The design goal was that structured data should be impossible to get subtly wrong: one place builds it, honesty rules are enforced in code, and a build-time validator fails the build if any page ships a broken `@id` graph or a fabricated price/rating. ## Changes - **One builder, one sink.** `utils/jsonLd.ts` holds pure, node-testable builders; `components/common/JsonLdGraph.astro` is the single escaped `<script type="application/ld+json">` sink (prevents `</script>` breakout XSS). - **The layout owns the page entity.** `BaseLayout` emits a baseline `Organization` + `WebSite` + `WebPage` graph on every page from its own `title`/`description`/canonical props. Enriched pages pass only what is specific to them: `pageType`, `breadcrumbs`, `mainEntityId`, and `extraJsonLd` nodes. This makes it impossible for a page's meta tags and its structured data to drift apart. - **Corrected site-wide entity.** Raster PNG logo (Google does not index SVG logos), real `sameAs` handles sourced from the footer links, `@id`-linked `Organization`/`WebSite`, and the triple-rendered head slot fixed. - **Honesty is enforced, not just intended.** No fabricated `Review`/`AggregateRating`/`Offer`. Pricing offers are parsed only from plain `$N` copy (a future "Contact us" drops the offer instead of shipping a garbage price). Third-party node packs and listed models do **not** claim Comfy Org as author/publisher. `noindex` pages (404, payment) emit no structured data. - **CI validator.** `pnpm --filter @comfyorg/website validate:jsonld` runs over `dist/` in the website build workflow and fails on invalid JSON, an unresolved `@id`, a fake rating, or an empty/non-numeric offer price. - **Breaking:** none. ## Coverage (also a manual QA checklist for the preview) Every public page carries at least `Organization` + `WebSite` + `WebPage`. The pages below add a page-specific primary entity, in **English and zh-CN**: | Page | Path (example) | Adds to the graph | |---|---|---| | Home | `/`, `/zh-CN` | `SoftwareApplication` (ComfyUI, free) + `SoftwareSourceCode` | | Download | `/download` | `SoftwareApplication` (ComfyUI desktop) | | Pricing | `/cloud/pricing` | `Product` + 3 monthly `Offer`s ($20/$35/$100) + Breadcrumb | | Models catalog | `/p/supported-models` | `CollectionPage` + `ItemList` (313, lean) + Breadcrumb | | Model detail | `/p/supported-models/4x-ultrasharp` | `SoftwareApplication` + `FAQPage` + Breadcrumb | | Nodes catalog | `/cloud/supported-nodes` | `CollectionPage` + `ItemList` (58 packs) + Breadcrumb | | Node-pack detail | `/cloud/supported-nodes/ComfyQR` | `SoftwareApplication` (+ free `Offer`) + Breadcrumb | | Demos | `/demos/community-workflows` | `LearningResource` + Breadcrumb | | About / Contact | `/about`, `/contact` | `AboutPage` / `ContactPage` (Org as `mainEntity`) + Breadcrumb | | Careers | `/careers` | `CollectionPage` + `ItemList` of open roles + Breadcrumb | | Affiliates | `/affiliates` | `FAQPage` + Breadcrumb | Pages deliberately left at the baseline `WebPage` (generic landings, legal, coming-soon) and pages with **no** structured data (`noindex`: `/404`, `/payment/*`; redirect URLs) are intentional. ## Review Focus - **Layout-owns-WebPage design.** `BaseLayout` builds the `WebPage`; pages contribute only extra nodes. This is the main structural decision and is what removes meta-vs-schema drift by construction. - **Honesty guardrails.** Worth confirming: pricing offers, third-party author omission on packs/models, and that `noindex` pages emit nothing. - **`@id` and URL consistency.** All cross-page links and `@id`s resolve to the canonical trailing-slash form; zh-CN breadcrumbs are rooted under `/zh-CN`; the singleton `WebSite`/`#software` entities carry one consistent definition across pages and locales. - **The validator.** It is a bespoke ~100-line script scoped to the website build job (not the prod deploy). Happy to make it non-blocking or drop it if the team prefers. - **Coordination with #13468.** Both branches add `components/common/JsonLdGraph.astro`. Customer pages are intentionally excluded here; #13468 can converge onto this shared builder. ## Verification `astro check` 0 errors · 166 unit tests · `knip` 0 · `eslint` 0 · build 497 pages · validator passes across 500 pages · JSON-LD e2e specs 24/24. (The 3 pre-existing demo e2e timeouts are an external Arcade-embed flake on one slug, reproduced identically on `main`.) ## Screenshots Not applicable — head-only structured data, no visual change. Validate on the Vercel preview with the Rich Results Test and the schema.org validator. Note: `@id`/URL values render as `comfy.org` (from `astro.config` `site`) even on the preview host, which is correct.