Plenty of small business sites have no Schema.org markup at all, or only the minimal LocalBusiness block a website builder generates: the business name, the address and nothing else. That minimal block is better than nothing. It still leaves out most of the fields an AI engine can use, and it skips six other types that help engines understand what a business is, what it offers and when it is open.
This post is the overview. Each section says what the type does and what sites usually get wrong, and links to a deeper guide where the Journal has one.
01. LocalBusiness — The Foundation Most Sites Underspecify
Every local business site should have a LocalBusiness block, or a more specific subtype such as Optician, Dentist or MedicalBusiness. Most sites include name, address, telephone and url. That passes a validator. It leaves out the fields that answer the questions people actually ask:
- geo — latitude and longitude, so there is no doubt which street and neighbourhood you mean.
- openingHoursSpecification — machine-readable hours. See section 07.
- priceRange — a short string such as
"$$", for price-qualified questions. - areaServed — the neighbourhoods you serve, named. See service-area schema.
- sameAs — the URLs of your Business Profile, Yelp page and other profiles, so an engine can tell they are one business. See sameAs and the identity graph.
{
"@context": "https://schema.org",
"@type": "Optician",
"name": "Example Optical",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Example Ave",
"addressLocality": "Brooklyn",
"addressRegion": "NY",
"postalCode": "11225"
},
"geo": { "@type": "GeoCoordinates", "latitude": 40.6602, "longitude": -73.9496 },
"telephone": "+1-718-555-0100",
"url": "https://exampleoptical.com",
"priceRange": "$$",
"sameAs": [
"https://www.yelp.com/biz/example-optical",
"https://maps.google.com/?cid=XXXXXXX"
]
}
If you have more than one location, the parent organisation and its locations need their own structure. See Organization parent declarations.
02. FAQPage — Questions Already Answered
AI engines answer questions. FAQPage markup labels which text on your page is a question and which is its answer, so an engine doesn't have to work that out from prose. Write the questions customers ask before booking, in their words: "Do you take my insurance?", "How long is a new patient exam?", "Do I need an appointment?" Answer each in a few plain sentences, and mark up only questions that are visible on the page.
Be clear about what it won't do. Since August 2023, Google shows FAQ rich results only for well-known government and health sites (Google Search Central). For most local businesses the value is parsing, not a bigger search listing. The full method is in how to write an FAQ section an engine can lift whole.
03. Service — Telling AI Exactly What You Offer
LocalBusiness says that you exist and where. Service says what you do. When someone asks for "contact lens fittings in Crown Heights", an engine looks for a page that connects that specific service to a specific provider in that place. One Service block per distinct offering makes the connection explicit.
{
"@context": "https://schema.org",
"@type": "Service",
"name": "Contact Lens Fitting",
"description": "Contact lens exams and fittings for adults and teenagers at Example Optical, Crown Heights, Brooklyn.",
"provider": { "@type": "Optician", "name": "Example Optical", "url": "https://exampleoptical.com" },
"areaServed": { "@type": "Place", "name": "Crown Heights, Brooklyn" }
}
Name, description, provider and area are the fields that matter. How to structure several services, and when to use Product instead, is in Service schema.
04. BreadcrumbList — Showing Where a Page Sits
BreadcrumbList states where a page sits in your site: home, then services, then a specific service. It is a small addition. It tells any crawler how your pages relate to each other, which helps when an engine has to choose between your homepage and a specific service page as the source for an answer. Give every page one that matches its visible breadcrumb.
05. Review / AggregateRating — Handle With Care
Ratings are among the things people weigh most, and it is tempting to put your star average in your markup. Two cautions. First, Google does not show review stars for reviews a LocalBusiness or Organization publishes about itself on its own site; it calls these self-serving (Google Search Central). Second, any rating you mark up must be real, current and visible on the page.
For most local businesses the better investment is the reviews themselves, on your Business Profile and the directories people already use. Engines read those directly. If you do mark up a rating, use your real figures:
{
"@context": "https://schema.org",
"@type": "Optician",
"name": "[Your practice]",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "[your rating]",
"reviewCount": "[your review count]"
}
}
06. Person — Connecting the Practitioner to the Business
When someone asks "who runs the optometry practice on [Avenue]?" or "who's a good private instructor in Brooklyn?", the answer is a person, not a business. Person markup gives the practitioner a machine-readable identity, their name, role and credentials, and connects it to the business with worksFor. For a solo practitioner, an instructor or a consultant, whose expertise is the thing being bought, it is worth the ten minutes.
{
"@context": "https://schema.org",
"@type": "Person",
"name": "[Practitioner name]",
"jobTitle": "[Role]",
"description": "[Name] is a [credential] and [role] in Brooklyn. State the credential, the training and the years in practice: the specifics are what an engine can quote.",
"worksFor": { "@type": "LocalBusiness", "name": "[Your business]", "url": "https://example.com" },
"url": "https://example.com/about"
}
07. OpeningHoursSpecification — Hours an Engine Can Read
"When are you open?" and "open now" are among the most common local questions. A text string like "Mon–Fri 9–6" makes an engine guess. OpeningHoursSpecification states each day's opening and closing time in a form it can read directly, and a second block can override the regular hours for holidays.
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "09:00",
"closes": "18:00"
}
Keep it in step with your Business Profile: hours that disagree between the two are worse than hours in one place only. Holiday overrides and the common mistakes are in how to mark up your hours.
This slot used to hold WebSite markup with a SearchAction, which powered the sitelinks search box in Google results. Google retired that search box in November 2024 (Google Search Central), so it no longer earns a place on a short list. Leaving an existing block in place does no harm.
Paste a URL into Google's Rich Results Test to see which Google features your markup is eligible for, and into the Schema Markup Validator to check it against schema.org. They test different things, so use both. The step-by-step version is in how to audit your structured data.
None of these seven needs a developer. They are JSON-LD blocks that live in the <head> of your pages or in your site builder's custom code settings.
If you are starting from nothing, add LocalBusiness with hours, then FAQPage on your main service pages, then a Service block per offering. Person and BreadcrumbList are quick additions after that. Mark up only what is true and visible on the page, and keep it current: markup that contradicts your Business Profile does more harm than none.