Skip to content

fix(seo): community JSON-LD times + Event/ProfilePage schema, canonical URLs, redirect cleanup - #1274

Open
LiamRandall wants to merge 4 commits into
mainfrom
seo-jsonld-events-redirects
Open

LiamRandall wants to merge 4 commits into
mainfrom
seo-jsonld-events-redirects

Conversation

@LiamRandall

@LiamRandall LiamRandall commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

SEO and structured-data fixes from the Sept 2026 Ahrefs site audit (93 pages with rich-result validation errors, 30 pages linking to redirects, redirect chains, an orphan page, and broken inbound URLs).

1. Community meeting times (every community page)

Meeting frontmatter only has a date, which Docusaurus turns into midnight UTC — 8 PM Eastern the previous evening. That value fed Event.startDate, VideoObject.uploadDate, the BlogPosting/Article datePublished, the /community/ list JSON-LD, and person-page meeting videos.

  • New src/theme/wasmcloud/community/meeting-time.ts: start = 1:00 PM America/New_York, DST-aware (hand-computed US rule, so SSR and hydration always agree), emitted with an explicit offset, e.g. 2026-09-23T13:00:00-04:00 / 2026-03-04T13:00:00-05:00. Optional start_time: 'HH:MM' frontmatter override for off-schedule calls.
  • Event.endDate = start + duration.

2. Event schema — online-event shape per schema.org/Event and Google's Event docs

VirtualLocation + OnlineEventAttendanceMode, plus the recommended image, offers (free, InStock, validFrom), an inline organizer (name + url, not just an @id ref), and performer.

3. People pages

  • Person is now wrapped in ProfilePage (mainEntity, dateModified) — Google's profile-page type.
  • Past conference talks were Event + Place with only a venue name and a Jan-1 year date → guaranteed validation errors. They're now CreativeWork (genre "Conference talk").
  • Meeting VideoObjects gain contentUrl/embedUrl (from the YouTube thumbnail) and duration.

4. Canonical URLs in JSON-LD

The site builds with trailingSlash: true, but JSON-LD url / @id / mainEntityOfPage / breadcrumb item were built from Docusaurus permalinks without the slash — pointing at 301s and not matching <link rel=canonical>. New withTrailingSlash() helper applied to blog, community, docs, course, collection-page, person-page, site-navigation, blog/community list pages, FAQ, glossary, and a thin wrapper of the docs BreadcrumbList. Search urlTemplate → /search/?q=.

5. Redirects (netlify.toml)

  • Simulated every rule against the build (first-match, splats, file shadowing, pretty-URL slash): 180 non-wildcard rules were multi-hop chains, lacked the trailing slash (extra hop), or dead-ended at a 404. All now point directly at the final page in one hop; 17 dead ends hand-mapped to the closest v1 page (e.g. docs/cli/wash#… was a relative path → /docs/v1/cli/wash/#…).
  • Quick links: /quickstart → /docs/quickstart/ (was the v1 tour, 3 hops), /cloud → /docs/kubernetes-operator/ (was v1, 4 hops), /edge → the edge blog post (was a dead v1 NGS page), /install → /docs/installation/.
  • New 301s for URLs that still rank but 404: /Examples/Typescript, /ecosystem, /docs/wash/language-support, /Platform%20Overview/Lattice.
  • Removed orphaned agenda stub community/2025-01-02-community-meeting.mdx (never authored, served at a date-based URL) → 301 to /community/. Note: it referenced recording ZqNy4337XLA, which has no other page.

6. Internal links

Every built <a href> that hit a redirect now links to the final URL (49 links / 36 files: v1 examples → add-features/, missing trailing slashes, /docs/roadmap/, old /docs/fundamentals/...). One broken 0.82 link fixed.

7. Docs

Verification

  • npm run build passes (onBrokenLinks/onBrokenAnchors: 'throw')
  • npm run validate:structured-data: 892 HTML files, OK
  • Google Rich Results Test (Code mode — deploy previews send x-robots-tag: noindex, so the URL mode reports "URL is not available to Google"):
    • Community meeting page: 10 valid items (Article, Breadcrumbs, Organization, Software Apps, Video), 0 errors; only optional aggregateRating on SoftwareApplication entities
    • Profile page (/people/bailey-hayes/): 76 valid items incl. Profile page, 0 errors; the 59 contentUrl/embedUrl warnings it reported are fixed in eb706bb
    • Event: Google's test detects no items for online-only events — confirmed with schema.org's own online-event example as a control, which also returns "No items detected". Virtual events aren't a Google rich-result type; the markup matches the schema.org example shape.
  • Scripted check of every JSON-LD node in the build against Google's required properties (Article/BlogPosting/TechArticle, VideoObject, Clip, BreadcrumbList, FAQPage/Question/Answer, Course, SoftwareApplication, ProfilePage, Event, Organization, DefinedTerm) and ISO-8601-with-offset dates: 0 errors. Remaining optional warnings: SoftwareApplication aggregateRating (no ratings to cite), TechArticle datePublished on undated docs, image on pre-2024 community pages / external writings.
  • Redirects on the deploy preview: /quickstart, /cloud, /edge, /install, legacy URLs, the deleted stub, and sampled legacy docs paths all resolve in 1 hop
  • Zero internal links in the build resolve through a redirect

…canonical URLs, redirects

- Anchor community meeting Event/VideoObject/BlogPosting/Article dates at
  1:00 PM America/New_York (DST-aware) instead of midnight UTC; Event gains
  image, offers, inline organizer per Google's online-event guidance
- People pages: wrap Person in ProfilePage; past talks emitted as
  CreativeWork (no address/time to satisfy Event)
- Normalize JSON-LD url/@id/breadcrumb items to trailing-slash canonicals
- Collapse 180 redirect chains / dead ends in netlify.toml to single hops;
  /quickstart and /cloud now point at v2 docs; add 301s for legacy URLs
- Remove orphaned 2025-01-02 agenda stub (301 to /community/)
- Fix internal links that hit redirects; v2 callouts on v1 wadm, lattice,
  and NATS pages; components page H1 names the Wasm Component Model

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Liam Randall <liam@cosmonic.com>
@netlify

netlify Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

❌ Deploy Preview for dreamy-golick-5f201e failed.

Name Link
🔨 Latest commit c5e483f
🔍 Latest deploy log https://app.netlify.com/projects/dreamy-golick-5f201e/deploys/6ac0223002dbe300081079d2

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Structured data validation

  • Mode: PR-incremental (base: origin/main)
  • Files checked: 896
  • JSON-LD payloads: 5106
  • Errors: 0
  • Warnings: 0

✅ All checks pass and no authoring warnings to backfill.

⚙️ Generated by ci_structured_data.yml • structured-data spike

…ation

Rich Results Test flagged 59 VideoObjects on /people/ pages with
'Either contentUrl or embedUrl should be specified'. Derive both from the
YouTube thumbnail and pass the meeting's duration through the people-pages
plugin.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Liam Randall <liam@cosmonic.com>
@LiamRandall
LiamRandall marked this pull request as ready for review September 24, 2026 00:19
@LiamRandall
LiamRandall requested a review from a team as a code owner September 24, 2026 00:19
@LiamRandall
LiamRandall enabled auto-merge (rebase) September 24, 2026 17:36
Signed-off-by: Liam Randall <liam.randall@gmail.com>
auto-merge was automatically disabled September 24, 2026 17:39

Rebase failed

Signed-off-by: Liam Randall <liam.randall@gmail.com>
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.

2 participants