Skip to content

fix: single enriched MusicEvent JSON-LD emitter per GSC findings#617

Merged
BreakableHoodie merged 1 commit into
mainfrom
fix/615-musicevent-jsonld
Jul 17, 2026
Merged

fix: single enriched MusicEvent JSON-LD emitter per GSC findings#617
BreakableHoodie merged 1 commit into
mainfrom
fix/615-musicevent-jsonld

Conversation

@BreakableHoodie

Copy link
Copy Markdown
Owner

Summary

Google's Events structured-data email flagged 5 missing-field warnings (offers.validFrom, image, offers.priceCurrency, organizer, eventStatus) — exactly the union of the gaps in the TWO duplicate MusicEvent JSON-LD blocks event pages emitted (SSR function + client SPA). The SSR function (functions/event/[slug].js) is now the sole emitter — crawlers fetch URLs fresh, so the server-rendered block is what search renders — enriched with everything the two blocks had between them plus the missing fields. Also removes price: "0", which told Google our ticketed events are free.

image is deliberately deferred to #616 (per-event poster_url — the only current asset is a 180px favicon, which would look worse in search results than the warning does).

Closes #615

What changed

File Change
functions/event/[slug].js created_at added to the event SELECT; MusicEvent gains organizer (SetTimes + Instagram sameAs, via CANONICAL_HOST), full-URL eventStatus/eventAttendanceMode, and offers.validFrom (regex-guarded date part of created_at; omitted when null/malformed); price: "0" removed, priceCurrency: CAD + availability kept
frontend/src/App.jsx Client-side MusicEvent block deleted (Organization/WebSite/Breadcrumb JSON-LD untouched); no dead code left
functions/event/__tests__/slug.test.js 3 new tests: full-URL enums + organizer, validFrom matches seeded created_at with no price key, offers absent without ticket_url

Documented trade-offs (Recommended-only fields, won't fail validation): validFrom uses site-publication date as the on-sale proxy (we don't track true on-sale dates); priceCurrency stands without price (we don't store prices — truthful currency beats an invented number).

Security / correctness notes

offers.url keeps the #504 read-path sanitization (normalizeHttpUrl). Client block deletion also removes a path where the raw unsanitized ticket_url reached JSON-LD. No auth surface.

Verification

  • Tests: backend 752 pass | 6 todo (74 files), slug.test.js 5/5; frontend 519 pass (50 files)
  • ESLint: 0 errors both stacks
  • Format check: clean both stacks
  • Build: green
  • validate:openapi: n/a — HTML-serving function, not in the API spec
  • Manual smoke: SSR tests assert the exact rendered JSON-LD; post-deploy, validate https://settimes.ca/event/lwbc17 in Google's Rich Results Test and confirm warnings clear in GSC once re-crawled

Built by Sonny · Reviewed by Vera & Theo · 🤖 Claude Code

Event pages emitted MusicEvent structured data twice (SSR + client),
and Google's Events email flagged five missing-field warnings that
were exactly the union of the two blocks' gaps. The SSR function is
now the sole emitter — crawlers fetch URLs fresh, so the server block
is what search renders — enriched with organizer (+ Instagram sameAs),
offers.validFrom (event creation date), and full-URL eventStatus /
eventAttendanceMode. The factually wrong price:"0" (free tickets!) is
removed; priceCurrency and availability stay. image deliberately
deferred to #616 (per-event posters).

Closes #615

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BreakableHoodie BreakableHoodie added bug Something isn't working priority:p2 Medium priority labels Jul 17, 2026
Copilot AI review requested due to automatic review settings July 17, 2026 11:43
@BreakableHoodie BreakableHoodie added bug Something isn't working priority:p2 Medium priority labels Jul 17, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority:p2 Medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(seo): MusicEvent JSON-LD emitted twice on event pages (SSR + client)

2 participants