fix(seo): JSON-LD validation and consistency patches#18011
Conversation
Replaces hardcoded https://ethereum.org/${locale}/... URLs with normalizeUrlForJsonLd(), which respects localePrefix "as-needed" (no prefix for the default locale). Affects breadcrumb items in the catch-all MDX route and the deposit-contract component's inline JSON-LD. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Moves the inline JSON-LD out of the React component and into a standard page-jsonld.tsx file alongside the route, matching the pattern used by every other page. Rewrites the schema to reflect the page's actual nature: - Single WebPage node (was WebPage + Article) - Uses ethereumFoundationOrganization / Community org entities instead of an inline "ethereum.org" Organization - No contributor or author attribution (page is a canonical reference, not collaboratively authored content shown with FileContributors) - `about` Thing kept under the WebPage Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Extracts the ethereum.org WebSite entity and the common trio of top-level graph nodes (EF Organization, Community Organization, WebSite) into shared constants: - ethereumOrgWebSite / ethereumOrgWebSiteReference - baseGraphNodes (the three entities every page's @graph includes) Each page's JSON-LD now spreads ...baseGraphNodes at the top of its @graph instead of repeating the three imports, and references the WebSite via ethereumOrgWebSiteReference in isPartOf instead of inlining the full object. Also consolidates the videos index page's inline publisher/reviewedBy full-org objects to their @id references, matching the site-wide pattern. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Per schema.org, reviewedBy is valid only on WebPage (and subtypes). Applies across the site: - Keep on WebPage / CollectionPage / FAQPage / AboutPage nodes - Swap to `editor` on Article and VideoObject nodes (both extend CreativeWork, where `editor` is valid) - Remove from ItemList nodes entirely (extends Intangible; neither reviewedBy nor editor applies) Total: 19 swaps, 6 removals across 25 files. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
✅ Deploy Preview for ethereumorg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
`editor` on CreativeWork has rangeIncludes: Person only, so using an Organization reference (EF) there is invalid per schema.org. The institutional "EF oversees this" signal is already conveyed by the containing WebPage's reviewedBy and the node's own publisher. Drop the third, invalid attribution rather than fabricate a Person or misuse a different property. Reverts the editor-swap portion of commit 1b1166e; keeps the reviewedBy removals on ItemList and the reviewedBy cleanup on WebPage-subtype nodes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
pettinarip
left a comment
There was a problem hiding this comment.
@myelinated-wackerow nice cleanup
Blockers / needs clarification
- PR description vs. diff mismatch on
editor. The summary saysreviewedBywas "swapped toeditoronArticleandVideoObjectnodes," but I can't find a singleeditor:insertion in the diff —reviewedByis simply removed from those nodes. deposit-contract/page-jsonld.tsxdrops theArticlenode. Every other extracted page emits both aWebPageand anArticle; this new file emits only aWebPage.
Nit
app/[locale]/staking/deposit-contract/page-jsonld.tsxdoesn't threadcontributorsthrough, so theWebPagelacks thecontributorarray the other extracted pages carry. Easy parity win now that it's a proper sibling file.
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
wackerow
left a comment
There was a problem hiding this comment.
Thanks @pettinarip!
- PR description vs. diff mismatch on
editor. The summary saysreviewedBywas "swapped toeditoronArticleandVideoObjectnodes," but I can't find a singleeditor:insertion in the diff —reviewedByis simply removed from those nodes.
Good catch, this was updated after the PR was posted—I've updated the PR description. Schema.org requires editor to be a Person not an Organization so this has been removed. The reviewedBy remains inconsistent with Article, so remains removed as well.
deposit-contract/page-jsonld.tsxdrops theArticlenode. Every other extracted page emits both aWebPageand anArticle; this new file emits only aWebPage.
This page isn't actually an article so semantically correct to leave off Article type for this page (likely others we could fine-tune as we keep iterating on this) cc: @mnelsonBT
app/[locale]/staking/deposit-contract/page-jsonld.tsxdoesn't threadcontributorsthrough, so theWebPagelacks thecontributorarray the other extracted pages carry. Easy parity win now that it's a proper sibling file.
Similarly, this page is one that doesn't really accept contributors (no FileContributors component nor "Edit" button) given the nature of this page, so was intentionally kept off.
This refactor causes breaking changes for the Authors changes in PR #17988 so I'm going to pull this in and update the other changes from there.
Thanks folks!

Summary
Four JSON-LD fixes packaged together.
Changes
Correct
reviewedBydomain. Per schema.org,reviewedByis valid only onWebPageand its subtypes.Swapped toremoved fromeditoronArticleandVideoObjectnodes (bothCreativeWork), andItemListnodes (no equivalent property applies). (Edit:editordoes not acceptOrganizationtype, onlyPerson-- has been removed)Drop
/en/prefix from JSON-LD URLs. Hardcodedhttps://ethereum.org/${locale}/...URLs now route throughnormalizeUrlForJsonLd, which respectslocalePrefix: "as-needed"(no prefix for the default locale).Extract
/staking/deposit-contract/JSON-LD to a sibling file. Previously inline inside the React component; now follows the standardpage-jsonld.tsxpattern alongside every other route. Uses the canonical EF/Community organization entities instead of a bogus inline "ethereum.org" Organization.DRY common
@graphentities. Extracts the ethereum.orgWebSiteentity and the trio of top-level graph nodes (EF Organization, Community Organization, WebSite) into shared constants. Each page now spreads...baseGraphNodesinstead of repeating them, and references the WebSite via@idinisPartOf.Note
Parallel to the author attribution work in:
Both touch
src/lib/utils/jsonld.tsand manypage-jsonld.tsxfiles but are not dependent -- whichever lands first, the other will need a merge resolution.Generated by Claude Opus 4.7