SEO playbook · Event structured data
Event Schema Markup for Resorts and Attractions: A Practical JSON-LD Guide
A practical guide to Event structured data for resorts and attractions: model event pages, dates, locations, offers, status, and validation without overstating rich-result guarantees.
Event structured data gives search engines explicit facts about a real event: its name, date, location, description, ticket offer, and current status. For resorts and attractions, it can help search systems understand seasonal festivals, concerts, races, guided experiences, special operating days, and other genuinely event-based pages.
It is not a guarantee of a carousel, a Maps placement, or a particular ranking. Google decides whether to show an enhanced result after considering the markup, the visible page, eligibility rules, and the search context. The job of the implementation is to make the event accurate, crawlable, current, and easy to validate.
In short:
- Put markup on a unique, indexable page focused on one event or one specific performance.
- Provide accurate name, startDate, and physical location data, including a detailed address when applicable.
- Use description, endDate, eventStatus, image, offers, organizer, and performer only when they describe visible, current page content.
- Keep dates, prices, ticket URLs, and availability synchronized with the booking system.
- Validate with Google’s Rich Results Test and the Schema Markup Validator, then monitor Search Console after deployment.
1. Start with the right page model
Google’s Event experience is designed around a page focused on a single event. Give each event a stable, unique URL and place the Event markup on that page. A resort calendar can still link to many event pages, but the calendar itself should not be treated as a substitute for the individual event pages when the goal is event rich-result eligibility.
This distinction matters for operators with recurring programming. A winter concert series, a Saturday fireworks show, and three separate race days may look similar in a CMS, but each occurrence can have a different date, offer, capacity, location, or cancellation status. Model them as separate event pages when guests can attend or buy tickets for them separately.
Do not use Event markup for ordinary products, season passes, trip packages, or short-term ticket promotions. If the page is primarily selling a product rather than describing a time-bound event, choose the structured-data type that matches that product and follow its own guidelines.
2. Build the required core accurately
For Google’s Event rich-result documentation, the core is more than three labels copied into JSON-LD. The event needs a descriptive name, an accurate startDate, and a physical location represented as a Place with a meaningful name and detailed address when the event happens at a venue.
- name: use the actual event title. Do not put the venue, price, performer, URL, or a short-term sales message in the name. “Sunset Concert at Alpine Base” is useful; “Concert – 20% Off Tickets” is not.
- startDate: use ISO 8601. Include the local start time and the correct UTC offset when the time is known. For an all-day event or an event whose start hour is not yet known, use a date without inventing midnight.
- location: use a real venue or representative location. Add location.name for the venue and a PostalAddress with the most complete accurate fields available. Do not repeat the event name in the location name.
If an event spans multiple days, provide both startDate and endDate in the same format. If separate performances have separate tickets, create a separate Event object and page for each performance rather than hiding distinct dates inside one generic series page.
3. Add recommended properties that stay current
Recommended properties improve the information available to search engines and guests only when the data is complete and maintained. Fewer accurate properties are better than a large block of stale or invented values.
- description: explain the specific experience, who it is for, and what guests need to know. Keep it aligned with the visible page copy.
- endDate: include the end time or date when the operator knows it. Do not fabricate a precise end time for an event that is genuinely open-ended.
- eventStatus: use scheduled, cancelled, postponed, or rescheduled status as appropriate. When an event is cancelled or postponed, keep the original identifying details and update the status instead of deleting the event’s dates and location.
- image: use crawlable images that represent the event. Multiple high-resolution aspect ratios can help with presentation, but they do not repair an inaccurate event page.
- offers: describe the available ticket offer or offers. Keep price, currency, availability, sale timing, and the public purchase URL synchronized with the booking experience.
- organizer and performer: add the host and participants when they are relevant to the event and visible on the page. Use names and URLs that identify real entities.
For resorts, the practical test is simple: if a guest can see it on the page or use it to make a booking decision, it may belong in structured data. If it is hidden, speculative, or only present to influence search, leave it out.
4. Use dates and status to handle real operating changes
Dates are where event markup most often becomes misleading. A mountain race can be postponed for weather, a fireworks show can be cancelled, and a ticketed dinner can move to another evening. Your structured data should reflect the same state guests see in the booking flow and on the event page.
- Scheduled: keep the published start date and current ticket information.
- Postponed: retain the original date that identifies the event and set the appropriate postponed status until the new date is known.
- Rescheduled: update the new start and end dates, and optionally provide the previous start date when the implementation supports it.
- Cancelled: retain the identifying event information and mark it cancelled rather than silently deleting the page or leaving it marked as scheduled.
Use the event’s local timezone and daylight-saving rules. If the hour is not known, use a date-only value instead of manufacturing a midnight timestamp. The same rule applies to a full-day operating event: express the day, not a false start time.
5. Model ticket offers without stale promises
Ticketing is where structured data becomes operational rather than merely technical. An offer should point to a public page where a guest can buy admission to that specific event. If there are several ticket types, model each relevant type accurately rather than publishing a price range that the booking page does not explain.
- Use a three-letter ISO currency code.
- Keep the price aligned with the lowest currently available price, including required fees where the Google guidance calls for them.
- Update availability when tickets go on sale, sell out, or become available for preorder.
- Use validFrom for date-restricted offers when appropriate.
- Make offers.url a direct, crawlable landing page where the public can buy the ticket—not a login-only route, a redirect chain, or a generic home page.
For dynamic pricing, the feed that generates the markup should be connected to the same source of truth as the booking flow. If the price or availability changes faster than the structured-data template updates, omit the field or reduce the automation scope until the data can be kept accurate.
6. Use JSON-LD as a maintainable implementation
Google supports JSON-LD, Microdata, and RDFa, and recommends JSON-LD for most implementations. Keep the block generated from the event record rather than hand-editing every page. The visible page and the JSON-LD must describe the same event.
Here is a compact example for a ticketed attraction event. Replace every value with the operator’s real event data before deployment:
{ "@context": "https://schema.org", "@type": "Event", "name": "Sunset Tram Ride and Stargazing", "startDate": "2026-08-15T20:30:00+02:00", "endDate": "2026-08-15T23:00:00+02:00", "eventStatus": "https://schema.org/EventScheduled", "location": { "@type": "Place", "name": "North Ridge Visitor Center", "address": { "@type": "PostalAddress", "streetAddress": "1 Mountain Road", "addressLocality": "Alpine Valley", "postalCode": "00000", "addressCountry": "ES" } }, "description": "An evening tram ride followed by guided stargazing.", "image": ["https://example.com/events/stargazing-16x9.jpg"], "offers": { "@type": "Offer", "url": "https://example.com/events/stargazing/tickets", "price": 35, "priceCurrency": "EUR", "availability": "https://schema.org/InStock" }, "organizer": { "@type": "Organization", "name": "Alpine Valley Park", "url": "https://example.com" } }If the event is online or mixed, use the relevant schema.org attendance and location properties, then test the implementation against the current Google guidance and the actual visible experience. Do not describe a virtual stream, physical venue, or ticket path that guests cannot use.
7. Validate in the right order
Use two validators for different jobs:
- Schema Markup Validator: check general Schema.org syntax, types, nesting, and values.
- Google Rich Results Test: check which Google rich-result features the page can generate and inspect the rendered result.
- Search Console: after Google has indexed the pages, monitor the relevant rich-result status report, inspect live URLs after template changes, and request validation after fixes.
For JavaScript-rendered sites, test the URL rather than assuming that a JSON-LD object present in source code will survive rendering. Confirm that the event page is crawlable, not blocked by robots rules or noindex, and that the rendered data matches the visible event page.
Common failures include a missing or generic address, a venue name placed in the event name, an incorrect timezone, an offer URL that cannot be crawled, sold-out tickets still marked in stock, and a cancellation that leaves the event marked scheduled. These are data-quality problems first and markup problems second.
8. Scale through one source of truth
At calendar scale, generate each event page and its JSON-LD from the same structured record that powers the guest-facing schedule and booking flow. Add automated checks for:
- unique event URL and stable identifier;
- valid event name, local date, timezone, and venue address;
- matching event status across CMS, ticketing, and page content;
- offer price, currency, availability, and public purchase URL;
- crawlable image and canonical page;
- no duplicate or contradictory Event blocks from multiple plugins or templates.
A calendar page can link to the individual event pages, and a recurring-event system can generate upcoming occurrences from a schedule. The important operating principle is that the pages intended for event discovery must resolve to concrete, current events with their own dates, locations, and ticket paths.
Where an integrated commerce platform can help
Structured data cannot fix disconnected inventory. If an operator sells event tickets, passes, rentals, lodging, and bundles through separate systems, the event page, offer data, and booking flow can drift apart. A shared commerce layer can reduce that gap by giving content, pricing, availability, and checkout a common source of truth.
Spotlio positions its platform around connected discovery, commerce, pricing, content, and mobile experiences for ski resorts, parks, and attractions. The useful evaluation question is not whether a platform promises richer search results; it is whether the operator can keep event pages, offers, availability, and booking destinations accurate as the operating season changes.