Schema.org for small businesses — Local SEO that actually works in 2026
For agritourism, salon, clinic: copy-paste JSON-LD plus what bonuses Google gives (rich results, knowledge panel, maps). Showing 4 schema types I drop in for clients and measurable effects.

Schema.org is that piece of code in <head> no one sees, but Google treats it as the operating manual for your business. It's the difference between "site in results" and "site with stars, opening hours, clickable phone, and a map next to the result". For a small business it's a free visibility bonus most clients don't capitalize on.
I'll show 4 schema types I roll out for clients (agritourism, vet, salon, shop), copy-paste code, and what to expect from Google.
What schema.org actually changes for a small business
Before you paste JSON-LD, understand the effects:
- Knowledge Panel sidebar, when someone searches your business by name, Google shows a card on the right with logo, hours, phone, map. No schema = no panel.
- Rich snippets in results, review stars, price ranges, "open now" hours, service list. Those 2 extra lines lift CTR ~30%.
- Google Maps integration, schema syncs with Google Business Profile (after verification). The map listing shows your site with correct data.
- Voice search, Google Assistant and Alexa read schema to answer "when is X open". No schema → "I don't know".
- AI Overviews / Bing Copilot, since 2025 LLMs read JSON-LD to return structured answers. Schema is your entry into AI search results.
This isn't the "stars used to work, now they don't" myth. In 2026 Google holds rich results for verified schema, but is stricter on data quality.
Schema #1 — LocalBusiness (the most important, every business)
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Pasieka Przygórze",
"image": "https://przygorze.pl/cover.jpg",
"@id": "https://przygorze.pl",
"url": "https://przygorze.pl",
"telephone": "+48602148729",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "Przygórze 12",
"addressLocality": "Mszana Dolna",
"postalCode": "34-730",
"addressRegion": "małopolskie",
"addressCountry": "PL"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 49.6800,
"longitude": 20.0830
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "09:00",
"closes": "18:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Saturday",
"opens": "10:00",
"closes": "14:00"
}
],
"sameAs": [
"https://www.facebook.com/pasiekaprzygorze",
"https://www.instagram.com/pasieka_przygorze"
]
}What's important here:
@id, unique identifier, used to dedupe if you have multiple schemata on the pagepriceRange, Google uses for "cheap / mid / expensive" filter on maps. Values:$,$$,$$$,$$$$or specific like"100-500 PLN"geo, coordinates allow zoom to map without geocoding. Check at google.com/maps via right click → "What's here"sameAs, links to social and other profiles. Google checks consistency (your FB page must have the same data)
Schema #2 — Service / Offers (for service providers)
Cosmetician, hairdresser, vet, mechanic:
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "Women's haircut",
"provider": {
"@type": "LocalBusiness",
"name": "Salon Eva",
"telephone": "+48512345678"
},
"areaServed": {
"@type": "City",
"name": "Mszana Dolna"
},
"offers": {
"@type": "Offer",
"priceCurrency": "PLN",
"price": "120",
"availability": "https://schema.org/InStock"
}
}Or AggregateOffer if you have a price range:
"offers": {
"@type": "AggregateOffer",
"priceCurrency": "PLN",
"lowPrice": "60",
"highPrice": "350",
"offerCount": 12
}For queries like "haircut price Mszana", Google shows a rich result with concrete prices.
Schema #3 — LodgingBusiness (agritourism, guesthouse, hotel)
A special LocalBusiness subtype for accommodations:
{
"@context": "https://schema.org",
"@type": "LodgingBusiness",
"name": "Agroturystyka U Marysi",
"description": "Wooden cottage in the Gorce mountains, Finnish sauna, breakfasts from homemade products.",
"image": ["https://umarysi.pl/hero.jpg", "https://umarysi.pl/sauna.jpg"],
"url": "https://umarysi.pl",
"telephone": "+48602148729",
"address": { /* as above */ },
"geo": { /* as above */ },
"priceRange": "200-450 PLN",
"amenityFeature": [
{ "@type": "LocationFeatureSpecification", "name": "WiFi", "value": true },
{ "@type": "LocationFeatureSpecification", "name": "Sauna", "value": true },
{ "@type": "LocationFeatureSpecification", "name": "Parking", "value": true },
{ "@type": "LocationFeatureSpecification", "name": "Breakfast", "value": true }
],
"starRating": {
"@type": "Rating",
"ratingValue": "4"
}
}LodgingBusiness gives extra SERP features:
- Price display in map results (requires
priceRange) - Filter by
amenityFeature(Google "lodgings with sauna") - Direct booking link if you have
/bookwithReservationschema
Schema #4 — MedicalBusiness / VeterinaryCare (clinic, practice)
For a vet:
{
"@context": "https://schema.org",
"@type": "VeterinaryCare",
"name": "AWET Veterinary",
"medicalSpecialty": ["VeterinaryEmergency", "Surgical"],
"availableService": [
{
"@type": "MedicalProcedure",
"name": "Sterilization",
"procedureType": "Surgical"
},
{
"@type": "MedicalProcedure",
"name": "Online consultation",
"procedureType": "Diagnostic"
}
],
"address": { /* ... */ }
}For a dentist: Dentist or MedicalClinic. For a psychologist: MedicalClinic with medicalSpecialty: "Psychiatry".
What MUST be consistent (most common mistake)
Google checks data consistency in 5+ places:
1. JSON-LD on the site (your schema)
2. Google Business Profile (on the map)
3. Facebook page (sameAs link)
4. Directory listings (Yelp, (sameAs link)
Foursquare, panoramafirm)
5. Domain and email (contact on site)All must have identical:
- Business name (literally string match)
- Address (Mszana Dolna ≠ Mszana Dolna PL ≠ ul. Górska 1, Mszana Dolna)
- Phone (+48 vs 0048 vs no prefix, pick one)
- URL (https vs http, www vs no www)
Inconsistency = Google treats as "not verified" and doesn't show rich results.
How to insert schema in Next.js
Simplest way:
// app/page.tsx
const localBusinessSchema = {
"@context": "https://schema.org",
"@type": "LodgingBusiness",
// ...
};
export default function HomePage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(localBusinessSchema) }}
/>
{/* page content */}
</>
);
}One <script> per schema type. You can have several (e.g. LocalBusiness + WebSite + BreadcrumbList).
How to verify it works
1. Google Rich Results Test (most important), paste URL, see if Google parses schema without errors: search.google.com/test/rich-results
2. Schema.org Validator, more detailed but looser about specific Google requirements: validator.schema.org
3. Search Console, "Enhancements" section, 2-4 weeks after deploy a "LocalBusiness" / "Article" / etc. section appears with the count of pages Google recognized.
4. Bing Webmaster Tools, Bing also reads schema, but has its own validator. Less important, but good for LinkedIn-traffic.
Measurable effects at clients (3-6 months)
Some case studies (anonymized):
Client A — agritourism in Mszana Dolna:
Before schema: 8 organic visits/day
After schema (LodgingBusiness + Service):
After 2 wks: 12/day (+50%)
After 6 wks: 18/day (+125%)
After 12 wks: 24/day (+200%)
Client B — vet:
Before: rich result only name + description
After schema (VeterinaryCare + emergencyService=true):
Appearance in "vet 24h Mszana"
3x increase in calls (Google forwarding number)
Client C — apiary:
Before: no knowledge panel
After schema (LocalBusiness + Product schema for products):
Knowledge panel with logo + map + hours
"Pasieka Przygórze" in Google Maps mobileCTR uplift averaging 30-80% in the first 3 months. Numbers come back fast.
Most common pitfalls
1. Fake reviews schema, TJUE and Google penalize "self-entered" review schema. Only aggregated reviews (Google, Booking, real platform) are legal.
2. Price in priceRange in PLN, Google sometimes doesn't convert, better use "price": "200", "priceCurrency": "PLN" in Offer instead of just priceRange: "200 PLN".
3. Multiple LocalBusiness on a page, if you have 3 locations, use one Organization with subOrganization or separate pages per location.
4. Schema without Google Business Profile, schema without GBP verification is weaker. Set up GBP even if you don't have a physical point (service-area business).
5. Outdated data, opening hours in schema as constants = problem during holidays. Better option: specialOpeningHoursSpecification with holiday dates.
TL;DR — checklist for every client
- LocalBusiness JSON-LD on home page (NOT just subpage)
-
name,address,telephone,geo(lat/lng),openingHoursSpecification -
sameAswith Facebook + Instagram (if active) - Special subtype if it fits (
LodgingBusiness,Restaurant,MedicalClinic, etc.) -
Serviceschema for each main service - Data consistency across GBP / Facebook / directories
- Test in Google Rich Results Test
- Verify in Search Console after 2-4 weeks
Schema.org is 30 minutes of work per client, gives measurable CTR uplift in 6 weeks. It's the best ROI in SEO I know for a small business.
If you want an audit of your setup or implementation on yours, drop a line. I also do Google Business Profile integration + consistency monitoring (with an alert if someone changes your data on Facebook).