Call or WhatsApp: +92 321 209 8738 WhatsApp: +971569803329 info@pixelsproagency.com

Schema Markup Guide

Schema Markup for Service Businesses: LocalBusiness, Service and FAQ JSON-LD That Validates

Schema markup will not rescue a weak page, but on a solid one it tells search engines exactly who you are, where you work, and what each service page offers. This guide gives service businesses complete, copy-paste JSON-LD for LocalBusiness, Service, and FAQPage, shows how to connect them with @id, walks through validation, and is honest about which parts Google currently rewards and which it ignores.

What Schema Markup Can and Cannot Do for a Service Business

Schema markup is a block of structured data, usually JSON-LD, that describes the page in a vocabulary search engines understand: this is a business, this is its phone number, these are its opening hours, this page describes a service. Google says it uses structured data to understand content and to make pages eligible for rich results. It does not describe structured data as a ranking boost, and adding more of it will not move a thin page up the results.

For a plumber, a dental clinic, a law firm, or a web agency, three types come up again and again: LocalBusiness (or one of its more specific subtypes), Service, and FAQPage. They do very different jobs, and Google treats them very differently. This guide gives you copy-paste examples for each, shows how to connect them so they describe one business rather than three strangers, and explains how to validate them. It ends with the parts Google currently ignores, so you do not spend an afternoon on markup that cannot pay off.

Where each type stands in Google Search today
TypeGoogle rich result?Where to use it
LocalBusiness and subtypesSupported (business details); name and address are requiredHome page or contact page, once per site
OrganizationSupported (logo, contact details, identity)Businesses without a public address
ServiceNo dedicated rich resultEach individual service page
FAQPageLimited since August 2023 to well-known government and health sitesPages that show visible questions and answers

Step 1: Choose LocalBusiness or Organization

Start with an honest question: can customers visit you at a real address? If you have a shop, clinic, office, or showroom listed in Google Business Profile, use LocalBusiness or a more specific subtype such as Dentist, Plumber, LegalService, AutoRepair, or ProfessionalService. Pick the most specific type schema.org offers for what you do, and fall back to LocalBusiness only when nothing closer exists.

If you work remotely, serve clients in other countries, or hide your address in Google Business Profile, Organization with areaServed is usually the more truthful choice. Structured data has to match what visitors can see. Publishing a street address in JSON-LD that appears nowhere on the page, just to qualify for a rich result, is the kind of mismatch Google’s guidelines warn against.

Step 2: Add a LocalBusiness Block

Here is a complete example for a fictional plumbing company. Every value is a placeholder. Replace each one with your real details, and delete any line you cannot fill in truthfully rather than guessing.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Plumber",
  "@id": "https://www.example.com/#business",
  "name": "Example Plumbing Co.",
  "url": "https://www.example.com/",
  "logo": "https://www.example.com/images/logo.png",
  "image": "https://www.example.com/images/storefront.jpg",
  "telephone": "+44 20 7946 0000",
  "email": "hello@example.com",
  "priceRange": "££",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "12 Sample Street",
    "addressLocality": "London",
    "postalCode": "N1 1AA",
    "addressCountry": "GB"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 51.53812,
    "longitude": -0.09914
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:00",
      "closes": "18:00"
    },
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday",
      "opens": "09:00",
      "closes": "13:00"
    }
  ],
  "areaServed": [
    { "@type": "City", "name": "London" }
  ],
  "sameAs": [
    "https://www.facebook.com/exampleplumbing",
    "https://www.linkedin.com/company/exampleplumbing"
  ]
}
</script>

A few details that matter in practice:

  • @id is a stable identifier you invent, normally your home page URL plus a fragment like #business. It does not need to resolve to anything. Its job is to let other blocks on other pages point back to this exact business.
  • telephone should include the country code, written the same way as on the page.
  • geo coordinates should be precise. Google’s local business documentation asks for at least five decimal places. Copy them from the pin in Google Maps, not from a city-centre lookup.
  • openingHoursSpecification uses 24-hour times. If you close for lunch, add two blocks for the same days rather than squeezing both into one.
  • sameAs lists your official profiles. Only include profiles you control and keep active.
  • Consistency matters more than completeness. The name, address, and phone number should match your Google Business Profile and your footer character for character. Our local SEO guide explains why those details need to match everywhere.

Step 3: Mark Up Each Service Page With Service

Most service businesses have one page per service: “Boiler repair,” “Teeth whitening,” “WordPress development.” The Service type describes what that page offers and who provides it. Google does not show a rich result for it, so set your expectations accordingly. Its value is clarity: it ties the page to your business entity and names the service and the area in a machine-readable way.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Service",
  "@id": "https://www.example.com/boiler-repair.html#service",
  "name": "Emergency Boiler Repair",
  "serviceType": "Emergency boiler repair",
  "description": "Same-day diagnosis and repair of gas combi and system boilers, including parts replacement and safety checks.",
  "url": "https://www.example.com/boiler-repair.html",
  "provider": { "@id": "https://www.example.com/#business" },
  "areaServed": [
    { "@type": "City", "name": "London" }
  ]
}
</script>

The important line is "provider": { "@id": "https://www.example.com/#business" }. Instead of repeating the whole business block on every service page, you reference the @id you defined on the home page. Keep serviceType plain and specific. “Emergency boiler repair” is useful. A string of ten keywords separated by commas is not.

Should you add offers with a price? Only if a price or price range is shown on the page and you keep it current. A stale price in markup is worse than no price, because it contradicts the page.

Step 4: Add FAQPage Only Where Questions Are Visible

In August 2023 Google limited FAQ rich results to well-known, authoritative government and health websites. For most businesses, FAQ markup will no longer produce the expandable questions under your listing. It is still valid schema.org markup and it still accurately describes the page, which is why the guides on this blog carry it. Just do not add it expecting extra space in search results.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Do you charge a call-out fee?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. The call-out fee covers the first hour on site and is listed on our pricing page."
      }
    },
    {
      "@type": "Question",
      "name": "Which areas do you cover?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "We cover all London postcodes inside the M25. Outside that area, call us to check availability."
      }
    }
  ]
}
</script>

Rules that keep FAQ markup clean:

  1. Every question and answer in the JSON-LD must appear on the page, word for word or very close to it.
  2. Use it for questions the business answers, not questions users submit and other users answer. That is a different type, QAPage.
  3. Do not repeat the same FAQ block across dozens of pages. Mark up each page’s own questions.
  4. Keep answers factual. Promotional answers (“We are the best in the city!”) add nothing for the reader or for search engines.

Step 5: Place the Markup on the Page

JSON-LD goes inside a <script type="application/ld+json"> tag. Google reads it in the <head> or the <body>. Put the LocalBusiness or Organization block on the home page (and the contact page if you like). Put Service on each service page, and FAQPage on any page with a visible FAQ section. You can have several separate script blocks on one page. Each one must be valid JSON on its own.

On WordPress, check what your SEO plugin already outputs before you paste anything. Yoast, Rank Math, and similar plugins usually emit an Organization or LocalBusiness graph. Adding a second hand-written business block with slightly different details gives search engines two conflicting descriptions of the same company. On a hand-coded site there is no plugin doing this for you, so the block has to be added and kept up to date by hand on every page that needs it.

Step 6: Validate With the Rich Results Test and the Schema Markup Validator

Use two tools, because they answer different questions.

  1. Before you publish, open Google’s Rich Results Test, choose the Code tab, and paste the full HTML of the page or just the script block.
  2. Read the result carefully. Red errors mean a required property is missing or malformed, and the item is not eligible. Orange warnings refer to recommended properties. They are worth fixing where the information exists, but they do not block eligibility.
  3. Expect Service not to appear at all. The Rich Results Test only reports types that Google uses for rich results, so a missing Service item is not an error.
  4. Paste the same code into the Schema Markup Validator. It checks against the full schema.org vocabulary, so it will show your Service block and flag misspelled properties that the Rich Results Test simply skips.
  5. After you publish, run the Rich Results Test again in URL mode. That catches problems introduced by your theme, a caching plugin, or a template that strips script tags.
  6. In Google Search Console, use URL Inspection to request indexing of the updated page, and watch the enhancement reports over the following weeks for any types Google reports on.
# check_jsonld.py: usage: python3 check_jsonld.py page1.html page2.html
import json, re, sys

pattern = re.compile(r'<script type="application/ld\+json">(.*?)</script>', re.S)
for path in sys.argv[1:]:
    html = open(path, encoding="utf-8").read()
    for i, block in enumerate(pattern.findall(html), start=1):
        try:
            data = json.loads(block)
            print(f"OK   {path} block {i}: {data.get('@type')}")
        except json.JSONDecodeError as err:
            print(f"FAIL {path} block {i}: {err}")

The short script above is a quick local check we use on static sites before uploading: it confirms every JSON-LD block on a page parses as valid JSON. It will not tell you whether Google likes the markup, but it catches the single most common failure — a trailing comma or a stray quote that silently breaks the whole block.

What Google Ignores (or Penalises)

  • Self-serving reviews. Since 2019, review stars are not shown for LocalBusiness and Organization markup when the business collects and displays reviews about itself on its own site. Adding aggregateRating to your own business block will not bring back the stars.
  • Made-up ratings. Marking up reviews or ratings that do not exist on the page breaks Google’s structured data guidelines and can lead to a manual action under Google’s general structured data guidelines.
  • Keyword stuffing in descriptions. The description property is read as a description. Stuffing it with keywords does not affect rankings and makes the markup look spammy.
  • HowTo markup. Google stopped showing HowTo rich results in 2023. You can leave existing markup in place, but adding new HowTo blocks will not produce rich results.
  • Markup for hidden content. Questions, prices, or addresses that exist only in the JSON-LD and not on the visible page are not eligible.

Common Mistakes

  • Copying a generator’s output without editing it. Online schema generators often fill in sample hours, placeholder coordinates, or a generic @type. Read every line before publishing.
  • Two business entities on one site. A theme outputs Organization, a plugin outputs LocalBusiness, and a hand-pasted block adds a third. Keep one, and reference it by @id.
  • Invalid JSON. Trailing commas, curly “smart” quotes pasted from a word processor, and unescaped double quotes inside answers are the usual culprits.
  • Forgetting to update it. New hours, a new phone number, or a move to new premises must be changed in the markup too. Add schema to your routine website maintenance checklist.
  • Expecting a rich result in days. Valid markup makes a page eligible. It does not guarantee anything, and Google decides when and whether to show enhanced results.

Schema works best on top of a page that is already solid: a clear title, real service details, and a visible address and phone number. If you are still working through those basics, start with our on-page SEO checklist and come back to structured data once the page itself says what the markup claims.

Frequently Asked Questions

Does schema markup improve Google rankings?

Google describes structured data as a way to understand a page and make it eligible for rich results, not as a ranking boost. Clear content and a good page come first. Markup helps search engines interpret them.

Should a service business use LocalBusiness or Organization?

Use LocalBusiness, or a specific subtype such as Dentist or Plumber, if customers can visit you at a real address shown on the site. If you work remotely or hide your address, Organization with areaServed is usually the more accurate choice.

Is FAQ schema still worth adding?

Since August 2023 Google shows FAQ rich results only for well-known government and health websites. FAQPage markup is still valid and describes visible questions accurately, but most businesses should not expect it to change how their listing looks.

Why does the Rich Results Test not show my Service markup?

The Rich Results Test only reports types Google uses for rich results, and Service is not one of them. Use the Schema Markup Validator at validator.schema.org to check Service blocks against the full schema.org vocabulary.

Can I add star ratings to my own LocalBusiness markup?

Google does not show review stars for LocalBusiness or Organization markup when the business displays reviews about itself on its own site. Marking up ratings that are not genuinely on the page also breaks Google's guidelines.

Not Sure Your Structured Data Is Right?

Send us a page URL and we will tell you what its markup says about your business — and what it should say.

Get in Touch