Schema markup is a short piece of JSON on the page that names what the page is. A person can read the sentences. A search engine can read the labels.
A Dublin SME site does not need every type on schema.org. Five cover the jobs that matter: who the business is, where it trades, what it sells, the questions it answers, and the guides it publishes. This page shows one example of each, where it goes, and how to check it. It sits beside the Page 1 of Google guide and the local SEO Ireland guide. Markup does not replace that work. It makes the same facts easier to read.
The examples use placeholders. Swap in your real name, URL, phone, and address. Do not leave YOUR_ values on a live page. If two pages disagree about the phone number, you have made the record worse, not better.
Organization — the business, once, on the homepage.
Organization says who you are as a company: the name, the site, the logo, and how to contact you. Put it on the homepage, not on every blog post.
Use the same legal or trading name you use on your Google Business Profile and on the footer. The @id is a stable URL for this business. Other types on the site point back to it so Google does not treat your service page and your homepage as two different companies.
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://yourdomain.ie/#organization",
"name": "YOUR_BUSINESS_NAME",
"url": "https://yourdomain.ie/",
"logo": "https://yourdomain.ie/logo.png",
"email": "hello@yourdomain.ie",
"telephone": "YOUR_PHONE",
"address": {
"@type": "PostalAddress",
"streetAddress": "YOUR_STREET",
"addressLocality": "Dublin",
"addressRegion": "Dublin",
"postalCode": "YOUR_EIRCODE",
"addressCountry": "IE"
}
}
The logo URL has to return an image. A broken logo link is a broken field. If you only have one office, this address and the LocalBusiness address must match character for character, including the Eircode.
LocalBusiness — where you trade, and when you are open.
LocalBusiness is Organization plus a place. It is the type that lines up with the map pack: address, hours, and the area you serve.
If a more specific type fits, use it. A dental clinic can be Dentist. A plumber can be Plumber. Both are LocalBusiness underneath. A vague type is still valid. A specific type is clearer. The local SEO guide covers the profile, the NAP, and the location pages this markup should agree with. The Google Business Profile guide is the listing itself. The schema should repeat that listing, not invent a second address.
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"@id": "https://yourdomain.ie/#local",
"name": "YOUR_BUSINESS_NAME",
"url": "https://yourdomain.ie/",
"telephone": "YOUR_PHONE",
"image": "https://yourdomain.ie/shopfront.jpg",
"address": {
"@type": "PostalAddress",
"streetAddress": "YOUR_STREET",
"addressLocality": "Dublin",
"postalCode": "YOUR_EIRCODE",
"addressCountry": "IE"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": "YOUR_LAT",
"longitude": "YOUR_LNG"
},
"openingHoursSpecification": [{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "09:00",
"closes": "17:30"
}],
"areaServed": { "@type": "City", "name": "Dublin" },
"parentOrganization": { "@id": "https://yourdomain.ie/#organization" }
}
Hours are in 24-hour time. If you close for lunch, use two blocks for that day. Do not publish hours you do not keep. A wrong closing time is a fact, and it is the kind of fact people act on.
Service — the thing you sell, tied to the business that sells it.
A service page that only has paragraphs can still rank. Service markup names the offer, the provider, and the area, so the page is not just a blob of text.
One page, one primary service. A clinic that does check-ups and implants can have two Service blocks, or two pages. Do not stuff five unrelated services into one description. Point provider at the LocalBusiness @id from the previous section.
{
"@context": "https://schema.org",
"@type": "Service",
"@id": "https://yourdomain.ie/services/your-service#service",
"name": "YOUR_SERVICE_NAME",
"serviceType": "YOUR_SERVICE_NAME",
"description": "One or two sentences on what the customer gets.",
"url": "https://yourdomain.ie/services/your-service",
"areaServed": { "@type": "City", "name": "Dublin" },
"provider": { "@id": "https://yourdomain.ie/#local" }
}
Leave price off unless the page shows that price in the visible copy. A price that exists only in the JSON and not on the page is a mismatch. If you do publish a price, the website cost guide is a separate topic: that page is about what a site costs, not about this markup.
FAQPage — only questions the page actually answers.
FAQPage is a list of questions and answers that are visible on the page. It is not a place to hide extra keywords.
Write the question the way a customer asks it. Answer it in the first sentences. The text in the JSON must match the text on the page. If you change the visible answer, change the JSON in the same edit. The questions at the bottom of this guide are the pattern: short, specific, and present on the page.
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [{
"@type": "Question",
"name": "What schema does a small business website need?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Start with Organization, LocalBusiness, Service, FAQPage, and Article. Use Organization for the company, LocalBusiness for the address and hours, Service for each offer, FAQPage for questions visible on the page, and Article for guides and posts."
}
}]
}
Add more questions as more objects in mainEntity. Skip a question you cannot answer from your own work. A FAQ that repeats the headline five times does not help a person, and it does not give an answer engine a clean fact to lift. That second job is the subject of the AI search ranking guide.
Article — the guide or post, with an author and a date.
Article marks a piece of writing: the headline, the description, who wrote it, and when it went up. Use it on guides and posts, not on the homepage.
The headline in the JSON should be the headline on the page. dateModified changes when you change the page in a way a reader should know about. A typo fix does not need a new date. A rewritten section does.
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "YOUR_ARTICLE_HEADLINE",
"description": "One sentence on what the article covers.",
"datePublished": "2026-10-07",
"dateModified": "2026-10-07",
"author": {
"@type": "Person",
"name": "YOUR_AUTHOR_NAME"
},
"publisher": { "@id": "https://yourdomain.ie/#organization" },
"mainEntityOfPage": "https://yourdomain.ie/resources/your-article"
}
You can put all five types in one script with @graph instead of five separate script tags. One script is easier to keep in sync. The rule does not change: every fact in the graph also appears in the visible page, and every ID points at a type you actually published.
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "Organization", "@id": "https://yourdomain.ie/#organization" },
{ "@type": "LocalBusiness", "@id": "https://yourdomain.ie/#local" },
{ "@type": "Service", "@id": "https://yourdomain.ie/services/your-service#service" },
{ "@type": "FAQPage" },
{ "@type": "Article" }
]
}
That last block is a sketch of the shape, not a finished graph. Copy the full fields from the five examples above into each object. An empty type with no name and no URL will fail validation, which is what you want. A failure you can see is better than a silent half-record.
Validate the markup before you call it done.
Two free checks. One tells you the JSON parses. The other tells you whether Google can read a rich-result type from it.
Three checks, in order
Schema Markup Validator
Open validator.schema.org, paste the page URL or the JSON, and read the errors by field name. Fix the field. Run it again. Warnings about optional fields can wait. Errors on name, URL, and address cannot.
Rich Results Test
Open Google's Rich Results Test on the live URL. A pass means the page is eligible for a rich result. It does not mean Google will show one, and it does not mean the page will rank.
Read it against the page
Compare the name, phone, address, hours, and FAQ answers to what a customer sees. If the JSON is right and the footer is wrong, fix the footer. The markup is a copy of the page, not a second source of truth.
Valid schema does not buy a ranking. It removes a reason for a machine to misunderstand the page. The ranking work is still the site, the pages, and the proof, which is what we run as an SEO retainer.
Five mistakes that make the markup worse than none.
Broken schema is not neutral. It publishes a second version of the business that the page itself contradicts.
- A different phone or Eircode in the JSON. If the footer says one number and LocalBusiness says another, fix the page first, then copy it.
- FAQ answers that are not on the page. FAQPage is a transcript of visible questions, not a keyword list.
- A price that the page does not show. Leave
priceout until the offer on the page states it. - Organization on every blog post with a new @id. One organization id for the whole site. Posts point at it. They do not invent a new company.
- Placeholder text left live. YOUR_BUSINESS_NAME on a public URL is a published error. Search the template strings before you deploy.
When those five are clean, the markup is ready to sit next to the AI search guide. Answer engines can only cite a fact you actually stated, and schema is how you label that fact. It is still the sentence on the page that has to be true.