Structured Data (JSON-LD)
Ready-to-paste blocks. These are the "hidden labels" that tell Google and AI assistants exactly what each page is, rather than making them guess from the prose.
How to add these in Next.js (App Router)
// components/JsonLd.tsx
export function JsonLd({ data }: { data: Record<string, unknown> }) {
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
/>
);
}
Then in any page:
import { JsonLd } from '@/components/JsonLd';
import { organizationSchema } from '@/lib/schema';
export default function Page() {
return (
<>
<JsonLd data={organizationSchema} />
{/* page content */}
</>
);
}
Put the schema objects in lib/schema.ts as typed exports so the org details live in exactly one place. That also prevents phone number inconsistencies structurally.
Before deploying, validate every block at validator.schema.org and Google's Rich Results Test.
Replace every [BRACKETED] value before shipping.
1. Organization — put this on every page
This is the master record. The @id lets every other block reference it instead of repeating the details.
{
"@context": "https://schema.org",
"@type": ["Organization", "TravelAgency"],
"@id": "https://www.snowmobileynp.com/#organization",
"name": "Yellowstone Snowmobile Tours",
"url": "https://www.snowmobileynp.com",
"logo": {
"@type": "ImageObject",
"url": "https://www.snowmobileynp.com/images/logo.webp"
},
"image": "https://www.snowmobileynp.com/api/media/hero-home.jpg",
"description": "Small-group, owner-led guided snowmobile tours of Yellowstone National Park departing from Jackson Hole, Wyoming. An authorized concessioner of the National Park Service.",
"telephone": "+1-307-690-5501",
"email": "[email protected]",
"foundingDate": "2026",
"founder": {
"@type": "Person",
"name": "Kyle James",
"jobTitle": "Owner and Lead Guide",
"description": "Longtime Jackson Hole resident with approximately 25 years guiding in the Greater Yellowstone Ecosystem."
},
"address": {
"@type": "PostalAddress",
"addressLocality": "Jackson",
"addressRegion": "WY",
"postalCode": "83001",
"addressCountry": "US"
},
"areaServed": [
{ "@type": "Place", "name": "Yellowstone National Park" },
{ "@type": "Place", "name": "Jackson Hole, Wyoming" },
{ "@type": "Place", "name": "Teton County, Wyoming" }
],
"knowsAbout": [
"Yellowstone National Park winter travel",
"Guided snowmobile tours",
"Yellowstone wildlife",
"Yellowstone geothermal features"
],
"sameAs": [
"[YOUR INSTAGRAM URL]",
"[YOUR FACEBOOK URL — if you create one]",
"[YOUR TRIPADVISOR URL — once created]",
"[YOUR GOOGLE BUSINESS PROFILE URL — once verified]"
],
"hasCredential": {
"@type": "EducationalOccupationalCredential",
"credentialCategory": "Authorized Concessioner",
"recognizedBy": {
"@type": "GovernmentOrganization",
"name": "United States National Park Service"
}
}
}
Note on address: no street address is included because you operate as a service-area business. Do not put a PO Box here. Once your Google Business Profile is verified, add the profile URL to sameAs — that link is what ties the two records together in Google's eyes.
Note on sameAs: leave out any placeholder you don't have a real URL for. Empty or fake values are worse than omission.
2. Tour pages — TouristTrip
One per tour page. This is the block that lets an AI assistant answer "how long is it, what does it cost, how old do my kids have to be."
Old Faithful Day Tour
{
"@context": "https://schema.org",
"@type": "TouristTrip",
"@id": "https://www.snowmobileynp.com/tours/old-faithful-day-tour#trip",
"name": "Old Faithful Full-Day Snowmobile Tour",
"description": "A full-day guided snowmobile tour to Old Faithful, roughly 90 miles round trip from Yellowstone's South Entrance through frozen waterfalls, snow-covered forests and geothermal basins. Breakfast and lunch included.",
"url": "https://www.snowmobileynp.com/tours/old-faithful-day-tour",
"image": "https://www.snowmobileynp.com/api/media/hero-oldfaithful.jpg",
"provider": { "@id": "https://www.snowmobileynp.com/#organization" },
"touristType": [
"Families",
"Couples",
"First-time snowmobilers",
"Wildlife enthusiasts"
],
"itinerary": {
"@type": "ItemList",
"numberOfItems": 5,
"itemListElement": [
{ "@type": "ListItem", "position": 1, "item": { "@type": "TouristAttraction", "name": "Flagg Ranch, Yellowstone South Entrance" } },
{ "@type": "ListItem", "position": 2, "item": { "@type": "TouristAttraction", "name": "Moose Falls" } },
{ "@type": "ListItem", "position": 3, "item": { "@type": "TouristAttraction", "name": "Lewis Canyon" } },
{ "@type": "ListItem", "position": 4, "item": { "@type": "TouristAttraction", "name": "West Thumb Geyser Basin" } },
{ "@type": "ListItem", "position": 5, "item": { "@type": "TouristAttraction", "name": "Old Faithful" } }
]
},
"subjectOf": {
"@type": "Place",
"name": "Yellowstone National Park",
"address": { "@type": "PostalAddress", "addressRegion": "WY", "addressCountry": "US" }
},
"offers": {
"@type": "Offer",
"price": "[PRICE]",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "[SEASON START, e.g. 2026-12-15]",
"url": "https://www.snowmobileynp.com/contact?tour=Old%20Faithful",
"seller": { "@id": "https://www.snowmobileynp.com/#organization" }
}
}
Three-Day Expedition
{
"@context": "https://schema.org",
"@type": "TouristTrip",
"@id": "https://www.snowmobileynp.com/tours/three-day-yellowstone#trip",
"name": "Three-Day Yellowstone Snowmobile Expedition",
"description": "A 3-day, 2-night guided snowmobile expedition covering roughly 170 miles of Yellowstone in winter, with two nights lodging in Montana gateway towns, all meals, and full gear included.",
"url": "https://www.snowmobileynp.com/tours/three-day-yellowstone",
"image": "https://www.snowmobileynp.com/api/media/hero-multiday.jpg",
"provider": { "@id": "https://www.snowmobileynp.com/#organization" },
"touristType": ["Adventure travelers", "Experienced riders", "Small private groups"],
"itinerary": {
"@type": "ItemList",
"numberOfItems": 3,
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@type": "TouristTrip",
"name": "Day 1 — Jackson to West Yellowstone",
"description": "Approximately 70 miles and 6–7 hours riding via Flagg Ranch. Lewis Falls, West Thumb Geyser Basin, Black Sand Basin, Fountain Paint Pots and Midway Geyser Basin. Overnight in West Yellowstone, Montana."
}
},
{
"@type": "ListItem",
"position": 2,
"item": {
"@type": "TouristTrip",
"name": "Day 2 — Yellowstone's Northern Wonders",
"description": "Re-entry through the West Entrance. Gibbon River, the Grand Canyon of the Yellowstone, Upper and Lower Falls, Madison River Valley, Firehole Canyon, Gibbon Falls and Sheepeater Cliff. Overnight in Gardiner, Montana."
}
},
{
"@type": "ListItem",
"position": 3,
"item": {
"@type": "TouristTrip",
"name": "Day 3 — Hayden Valley and Return to Jackson",
"description": "Approximately 95 miles and 7–9 hours riding through Hayden Valley, Mud Volcano and Fishing Bridge, exiting the South Entrance with Teton views on the return. Arrive Jackson 5:00–6:00 p.m."
}
}
]
},
"offers": {
"@type": "Offer",
"price": "[PRICE]",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://www.snowmobileynp.com/contact?tour=Multi-Day",
"seller": { "@id": "https://www.snowmobileynp.com/#organization" }
}
}
Build the Grand Canyon and Custom Tour blocks on the same pattern. For Custom Tours use "availability": "https://schema.org/PreOrder" and omit price, or use an AggregateOffer with lowPrice once you know your floor.
3. Individual departures — Event
Once you publish a departure calendar, add one Event per scheduled date. This is what makes "is there a tour on January 14?" answerable.
{
"@context": "https://schema.org",
"@type": "Event",
"name": "Old Faithful Snowmobile Tour — January 14, 2027",
"startDate": "2027-01-14T06:30:00-07:00",
"endDate": "2027-01-14T17:30:00-07:00",
"eventStatus": "https://schema.org/EventScheduled",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"location": {
"@type": "Place",
"name": "Yellowstone National Park — South Entrance / Flagg Ranch",
"address": {
"@type": "PostalAddress",
"addressLocality": "Moran",
"addressRegion": "WY",
"addressCountry": "US"
}
},
"organizer": { "@id": "https://www.snowmobileynp.com/#organization" },
"offers": {
"@type": "Offer",
"price": "[PRICE]",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://www.snowmobileynp.com/contact?tour=Old%20Faithful",
"validFrom": "[DATE YOU OPEN BOOKING]"
}
}
Generate these programmatically from the same data source that renders the calendar. Do not hand-write them.
4. FAQ page — FAQPage
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Is snowmobiling hard?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Most of our guests are first-time snowmobile riders or have only ridden on guided tours. Before your tour begins, our guides provide a thorough safety briefing and operating instructions. We use Ski-Doo Grand Touring snowmobiles, designed specifically for trail riding and known for smooth handling, comfort, quiet operation and reliability, with comfortable seating for a driver and passenger."
}
},
{
"@type": "Question",
"name": "What gear is provided and will I stay warm?",
"acceptedAnswer": {
"@type": "Answer",
"text": "We provide all specialized snowmobile gear including an insulated jacket and bibs, snow boots, a full-face helmet and insulated mittens. We recommend wearing layered clothing underneath. Between the insulated gear, heated handlebars and the snowmobile windshield, most guests are surprised by how comfortable they stay even in cold weather."
}
},
{
"@type": "Question",
"name": "How many people are in a tour group?",
"acceptedAnswer": {
"@type": "Answer",
"text": "[STANDARDIZE THIS NUMBER — see audit item 3.1. Your FAQ page and Multi-Day page currently disagree.]"
}
},
{
"@type": "Question",
"name": "How old do you have to be to snowmobile in Yellowstone?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Passengers must be at least 8 years old, with 10 and up recommended. Drivers must be at least 16 and hold a valid driver's license."
}
},
{
"@type": "Question",
"name": "Where do your Yellowstone snowmobile tours depart from?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Tours depart from Jackson, Wyoming with complimentary pick-up from your Jackson lodging. Snowmobiling begins at Flagg Ranch near Yellowstone's South Entrance."
}
},
{
"@type": "Question",
"name": "Do I need a guide to snowmobile in Yellowstone?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, with one narrow exception. Yellowstone's interior roads are closed to regular vehicles in winter and open only to oversnow travel from roughly mid-December to mid-March. Visitors must travel by guided snowmobile, guided snowcoach, or through the park's limited non-commercially guided lottery program, which requires winning a permit in advance."
}
},
{
"@type": "Question",
"name": "What is your cancellation and weather policy?",
"acceptedAnswer": {
"@type": "Answer",
"text": "[WRITE THIS — see audit item 3.5. It is a real objection for winter buyers and you currently have no answer published.]"
}
}
]
}
Honest expectation: Google restricted FAQ rich results to government and health sites in 2023, so this probably will not show dropdowns in search results. Add it anyway — AI answer engines parse it directly, and it costs nothing. Add the last four questions to the visible FAQ page too; schema must always match visible content.
5. Breadcrumbs — on every page below the homepage
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.snowmobileynp.com" },
{ "@type": "ListItem", "position": 2, "name": "Tours", "item": "https://www.snowmobileynp.com/tours" },
{ "@type": "ListItem", "position": 3, "name": "Old Faithful Day Tour", "item": "https://www.snowmobileynp.com/tours/old-faithful-day-tour" }
]
}
Generate from the route segments rather than hardcoding per page.
6. Reviews — add only when real
Once you have real reviews, add aggregateRating to the Organization block. This is a property fragment, not a standalone block — nest it inside the Organization object from section 1:
// add as a property of the Organization object above
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "5.0",
"reviewCount": "27",
"bestRating": "5"
}
Do not add this before you have real reviews displayed on the page. Fabricated or unsupported review markup is an explicit Google policy violation and carries a manual penalty. The rating must match reviews that are visibly published on your site.
Implementation order
- Organization on every page — 30 min
- TouristTrip on the four tour pages — 1 hr
- BreadcrumbList sitewide — 30 min
- FAQPage — 30 min (after standardizing group size and adding the cancellation policy)
- Event per departure — once the calendar exists, generated from data
- AggregateRating — once you have real reviews