Skip to content
Instant · runs in your browser

Local Business Schema Generator With 80 Business Types

Address, hours and geo into LocalBusiness JSON-LD - 80 subtypes supported.

Local business schema generator output does one job well and one job badly if you let it: it describes a physical location to a search engine, and it quietly contradicts your Google Business Profile if you're careless with a single character. The markup itself is not complicated. The discipline around it is. This tool covers seventeen fields, an eighty-name type whitelist, and an opening-hours parser that turns human shorthand into the structure Google actually documents.

Leave blank unless you know you need it. If you type something Google does not recognise, we flag it rather than putting a made-up type in your markup.

Full links starting with https://, not /photos/loaf.jpg. Google likes having the same photo in wide, standard and square crops.

Start with + and the dialling code, e.g. +1 for the US, +44 for the UK.

The full name is fine. A postal abbreviation like NY works too.

Latitude then longitude, separated by a comma. Right-click your pin in Google Maps and the first line of the menu is exactly this.

Two-letter days (Mo Tu We Th Fr Sa Su), a range with a hyphen, then the times on a 24-hour clock.

LinkedIn, X, Instagram, Wikipedia, Crunchbase - anywhere official that represents the same organisation. This is how Google connects the profiles to you.

Pick the narrowest local business schema type

The More specific type field is where most of the value sits. LocalBusiness is a valid @type and it's also the least informative thing you can say about a business. Restaurant, Dentist, Plumber, HairSalon, and SelfStorage all tell a search engine what the place does before it reads a word of your copy.

The field accepts any of about eighty schema.org types that inherit from LocalBusiness, grouped roughly as:

  • Food - Restaurant, Bakery, BarOrPub, Brewery, CafeOrCoffeeShop, FastFoodRestaurant, IceCreamShop, Winery.
  • Health and beauty - Dentist, Physician, Optician, Pharmacy, BeautySalon, DaySpa, HairSalon, NailSalon.
  • Trades - Electrician, GeneralContractor, HVACBusiness, HousePainter, Locksmith, MovingCompany, Plumber, RoofingContractor.
  • Lodging - Hotel, Motel, Hostel, BedAndBreakfast, Resort.
  • Retail - Store plus around 20 subtypes: BookStore, ClothingStore, GroceryStore, HardwareStore, JewelryStore, PetStore, TireShop, and so on.
  • Services - Attorney, Notary, RealEstateAgent, TravelAgency, EmploymentAgency, FinancialService, ProfessionalService, Gym.

Type something that isn't on the list and it is not emitted. You get a notice saying the value wasn't recognized and the output falls back to LocalBusiness. That's deliberate: a @type that doesn't exist on schema.org makes the entire node meaningless to a parser, and a generator that invents types to please you is a generator that ships broken markup. Bakery works. Bakeries doesn't. CoffeeShop doesn't either - the real type is CafeOrCoffeeShop.

Keep your local business schema details aligned

This is the rule that costs people rankings, and it has nothing to do with schema syntax. The name, street address, and phone number in your markup should match your Google Business Profile character for character. Not "close enough". Not "Ave" here and "Avenue" there. Not a call-tracking number in the markup and the real number on the profile.

The address is split across 5 fields because PostalAddress is a structured object, not a string:

  • streetAddress - 148 Lafayette St. Suite numbers go here.
  • addressLocality - the city.
  • addressRegion - state or region. NY, not New York.
  • postalCode - as written locally.
  • addressCountry - the 2-letter ISO 3166-1 code. US, not USA and not United States.

Street address, city, and country are treated as required. Region and postal code are strongly recommended and are the 2 people skip most often.

Opening hours the parser understands

The openingHours box takes one rule per line and converts it into openingHoursSpecification, which is the shape Google documents. It is not the legacy openingHours string property.

Accepted forms:

Mo-Fr 09:00-17:00
Sa 10:00-14:00
Su closed

2-letter abbreviations and full day names both work, and so do Mon, Tues, Thur. A day range expands across the week correctly, including ranges that wrap - Fr-Mo produces Friday, Saturday, Sunday, Monday. Times shorter than 4 digits get zero-padded, so 9:00 becomes 09:00. A line marked closed publishes nothing for that day rather than emitting a zero-length interval, which is the correct behavior and not what most generators do.

A line the parser can't read is skipped with a notice quoting the line back to you. Weekdays 9-5 fails. Mo-Fr 09:00-17:00 doesn't.

Coordinates, price range, and the fields people skip

  • geo - one line, 40.7191, -74.0004. Comma, semicolon, or whitespace separated. If both halves don't parse as numbers, the field is dropped and you get a notice. Coordinates help disambiguate a location whose street address is ambiguous or newly assigned.
  • priceRange - a short symbol range like $$, or a currency range like $40-$120. Free text, no validation, but keep it short.
  • image - one absolute URL per line. Relative paths raise a notice, because a relative URL in JSON-LD resolves against the document base and breaks the moment the block is syndicated or read out of context.
  • sameAs - one profile URL per line. This is the field that links your entity to entities a search engine already knows: your LinkedIn company page, your Facebook page, your Wikipedia entry if you have one. Only include profiles that unambiguously identify the same business.

The aggregateRating trap

The ratingValue, reviewCount, and bestRating fields build an aggregateRating node, and there are 2 things to know before you use them.

First, mechanics: rating value and review count are both required for the node. Supply one without the other and the whole aggregateRating is dropped rather than shipped incomplete, with a notice explaining why. bestRating defaults to 5 if you leave it blank.

Second, and more important: Google ignores self-serving reviews. A rating you publish about your own business, on your own website, is not eligible to produce a review snippet. Marking up the average of testimonials you collected yourself does not change that. The fields exist because aggregateRating is legitimate when you're a third party aggregating reviews of someone else - a directory, a review site, a comparison page. On your own site it is markup that will be read and disregarded.

A worked local business schema example

A plumber in Brooklyn, subtype Plumber:

{
  "@context": "https://schema.org",
  "@type": "Plumber",
  "name": "Ridgewood Drain & Pipe",
  "image": "https://example.com/img/storefront.jpg",
  "url": "https://example.com",
  "telephone": "+1 718 555 0142",
  "priceRange": "$$",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "1420 Wyckoff Ave",
    "addressLocality": "Brooklyn",
    "addressRegion": "NY",
    "postalCode": "11237",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": "40.7043",
    "longitude": "-73.9089"
  },
  "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"
    }
  ],
  "sameAs": ["https://www.linkedin.com/company/example"]
}

Sunday is absent because the input said Su closed. One image, so image is a string rather than an array. Both forms are valid.

One block per location. A 3-branch business gets 3 pages and 3 blocks, each with its own address and hours, not one node with 3 addresses. If you're managing structured data across dozens of location pages, BlazeHive automates SEO content end to end, schema included.

Frequently Asked Questions

Does LocalBusiness markup get me into the map pack?

No. Local pack placement is driven by your Google Business Profile, proximity, and prominence. Markup helps a search engine confirm and reconcile the details it already has; it isn't an entry point to local results on its own.

What if I don't have a storefront customers can visit?

Then LocalBusiness is the wrong type. A service-area business with no public address should use Organization, or set the service area on the Business Profile and skip the street address in markup rather than publishing a home address.

Which subtype should I use if 2 fit?

The more specific one, as long as it's accurate. A bakery with seating is Bakery, not Restaurant and not FoodEstablishment. If nothing on the list fits cleanly, LocalBusiness is a fine answer.

Do I need coordinates if I have a full address?

Not strictly. They're recommended and they help for locations with ambiguous, new, or informally written addresses. Get them from the map pin, not from a geocoder guess.

Why did my opening hours disappear from the output?

The line didn't parse. Look for a notice quoting it back. The usual causes are missing minutes (9-5), a word instead of a day name (Weekdays), or a day abbreviation not in the accepted set.

Can I put this block on every page of my site?

You can, but the value is on the location page and the contact page. Repeating it site-wide doesn't strengthen the signal, and it makes every page a maintenance liability the next time your hours change.

Related free tools

All tools →