WHITNEY MUSEUMSELECTED WORK
EVENT STRUCTURED DATA
The project
The Whitney’s event pages passed Google’s Rich Results Test but did not appear in Google’s event results. I found the cause: one URL stood in for many dated occurrences, so Google could not read any of those pages as a single event.
What I did
I compared the team’s Rich Results Test with the live calendar, documented the cause page by page, sorted every kind of calendar event by eligibility, and wrote eight recommendations with example JSON-LD for the development team.
One page for a run of dates
The team’s test reported one valid item, but the tested page described a recurring tour, not one dated occurrence. Several calendar entries pointed to that same permanent page for the “Untitled” (America) tour, which had no date or time of its own.
I recommended a dedicated page and matching markup for each dated occurrence.
The same pattern across the calendar
The Biennial floor 5 tour page stood in for three tours across two days, and the Weekend Member Mornings page covered both days of a weekend. On July 16 the Storytime series page said the July 12 event had passed while the four-month series was still running.
One URL, many occurrences (calendar as of July 16, 2026)
| Page | What it represented |
|---|---|
/events/untitled-america-exb-tour | The July 11 noon tour, the July 12 noon tour and every later occurrence |
/events/tour-whitney-biennial-2026-floor5 | Tours on July 11 at 11 am and 2 pm, and July 12 at 11 am |
/events/wmm-july26 | Weekend Member Mornings on both July 11 and July 12 |
/events/storytime | A four-month series; on July 16 it said the July 12 event had passed |
Free programs linked to evergreen pages
The calendar sent Free Friday Nights and Free Second Sundays to evergreen program pages under /visit/. I recommended linking to dated event pages instead, each linking back to its program page.
I also flagged a content risk. Google’s guidelines don’t allow business hours, short-term discounts or purchase opportunities to be marked up as events, and a page that only says admission is free from 5 to 10 pm reads as exactly that. I recommended that each dated page lead with that date’s tours, performances, art making or Storytime, and treat free admission as an attribute of the event. The calendar already listed Storytime, All Ages Artmaking and exhibition tours for Free Second Sundays.
Where the calendar linked the free programs
| Calendar entry | Linked to |
|---|---|
| Free Friday Nights, Friday, July 10, 2026, 5 to 10 pm | /visit/free-friday-nights |
| Free Second Sundays, Sunday, July 12, 2026, 10:30 am to 6 pm | /visit/second-sundays |
Eligibility by event type
I sorted the calendar’s events by how each one should be handled. Free and ticketed events need different offer data, and recurring programs need a page per date. Google excludes events that require a membership or an invitation, so I told the team not to count their absence from event results as an implementation failure.
How I recommended handling each kind of event
| Event type | Examples | Recommendation |
|---|---|---|
| Free dated programs | Free Friday Nights, Free Second Sundays | A dated event page for each date. offers.price set to 0 with priceCurrency and availability, and isAccessibleForFree set to true |
| Tours free with museum admission | Exhibition tours | Not free to attend. The offer reflects the applicable admission price, not 0 |
| Recurring tours and series | Daily exhibition tours, Storytime | A unique dated URL for each occurrence. The evergreen program can act as the superEvent parent where appropriate |
| Programs inside a larger event | Storytime and All Ages Artmaking on a Free Second Sunday | Each gets its own dated page and Event markup, linked to the umbrella event through subEvent |
| Member-only events | Weekend Member Mornings, Member Nights, Member Preview Days | Ineligible. Google requires events to be bookable by the general public, so these stay out of visibility forecasts |
| Past occurrences | Storytime on July 12 | Removed from the active calendar’s crawl path, or pointed to the next occurrence |
Eight recommendations
The recommendations cover URLs, page content, event markup, expired listings and syndication. Keeping the evergreen program pages as hubs preserves the internal-linking benefit I identified in January.
- A dated URL for every occurrence
For example
/events/free-friday-nights-2026-08-14, and the same for daily tours and series like Storytime. - An event page for every free date
Every Free Friday Nights and Free Second Sundays date gets its own page, and the calendar links there instead of to
/visit/. - Keep the program pages as hubs
The permanent pages stay, and every dated page links back to its program hub.
- Lead with the programming
Describe the tours, performances and art making on that date. Free admission is a detail of the event.
- Connect parent and child events
Use superEvent and subEvent, so Storytime and All Ages Artmaking read as part of that day’s Free Second Sundays.
- Complete offers
Price 0 only when an event is truly free. A tour that’s free with museum admission isn’t free to attend.
- Clear out expired listings
Don’t leave the calendar pointing at pages that only say “This event has passed” while the series continues.
- Syndicate the free programs
List them on Google Business Profile and Facebook Events, which reach places on-page markup doesn’t.
Connecting events to the site-wide schema
This work extended my site-wide schema recommendations for whitney.org. The two new event blocks reference the Organization, WebSite and Museum entities already defined there by @id, so every event points to the same venue.
Schema blocks for whitney.org
- Block 1, on every page
- Identity layer: Organization, WebSite and WebPage. Covered in the site-wide recommendations
- Block 2, visit pages
- Museum. Covered in the site-wide recommendations
- Block 3, individual event pages
- WebPage and Event in one graph, shown on a dated Free Friday Nights page
- Block 4, events with child programs
- Event with subEvent references, shown on a dated Free Second Sundays page
Example JSON-LD
Block 3 goes on a dated Free Friday Nights page with the Block 1 identity layer. A WebPage node’s about and mainEntity point to the event, and the offer sets price 0 only because the night is free. Block 4 follows the same pattern for Free Second Sundays and lists Storytime and artmaking in subEvent, each with its own dated page.
Placeholders mark what the team had to supply before launch: the date’s programming, public images at 16:9, 4:3 and 1:1, and the RSVP date. I also asked them to confirm the URL patterns with the CMS team and review the non-critical issues from their test, which were not the reason the events were missing.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "WebPage",
"@id": "https://whitney.org/events/free-friday-nights-2026-08-14/#webpage",
"url": "https://whitney.org/events/free-friday-nights-2026-08-14",
"name": "Free Friday Nights, August 14, 2026",
"isPartOf": {
"@id": "https://whitney.org/#website"
},
"about": {
"@id": "https://whitney.org/events/free-friday-nights-2026-08-14/#event"
},
"mainEntity": {
"@id": "https://whitney.org/events/free-friday-nights-2026-08-14/#event"
}
},
{
"@type": "Event",
"@id": "https://whitney.org/events/free-friday-nights-2026-08-14/#event",
"name": "Free Friday Nights",
"url": "https://whitney.org/events/free-friday-nights-2026-08-14",
"startDate": "2026-08-14T17:00:00-04:00",
"endDate": "2026-08-14T22:00:00-04:00",
"eventStatus": "https://schema.org/EventScheduled",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"description": "[FILL: Describe the programming taking place on this date, such as gallery tours, live performance, or artmaking. Lead with the experience, not the admission price.]",
"image": [
"https://whitneymedia.org/[FILL: 16x9 image URL].jpg",
"https://whitneymedia.org/[FILL: 4x3 image URL].jpg",
"https://whitneymedia.org/[FILL: 1x1 image URL].jpg"
],
"isAccessibleForFree": true,
"location": {
"@type": "Place",
"@id": "https://whitney.org/#museum",
"name": "Whitney Museum of American Art",
"address": {
"@type": "PostalAddress",
"streetAddress": "99 Gansevoort Street",
"addressLocality": "New York",
"addressRegion": "NY",
"postalCode": "10014",
"addressCountry": "US"
}
},
"offers": {
"@type": "Offer",
"url": "https://whitney.org/events/free-friday-nights-2026-08-14",
"price": 0,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "[FILL: Date that tickets or RSVPs open, in ISO 8601 format]"
},
"organizer": {
"@type": "Organization",
"@id": "https://whitney.org/#organization",
"name": "Whitney Museum of American Art",
"url": "https://whitney.org/"
}
}
]
}Scope
Handoff scope
The handoff covered public events with dated pages. I separated member-only events, which Google does not show in event results, and gave the team a way to validate the revised pages.