Short answer: for a South African business site, a good LocalBusiness block needs only two things to be valid for Google, name and address, but it's only useful when every value matches what's visible on the page and on the Google Business Profile: a full PostalAddress with addressCountry: "ZA", the phone number in international format (+27, without the leading 0), opening hours in 24-hour time, and the most specific business type you can find. Leave out review stars about yourself, because Google won't show them.
Below is a walkthrough with a copy-paste example, plus the South Africa-specific details that tend to go wrong.
1. What Google actually requires
Google's Local Business structured data documentation lists only two required properties:
-
name: the business name -
address: aPostalAddress, with "as many properties as possible"
Recommended properties include telephone, url, geo, openingHoursSpecification, priceRange and department. (menu and servesCuisine only matter for food businesses.)
Two things the docs also say, which are worth remembering before you promise anyone "rich results":
- Use the most specific subtype you can (e.g.
Plumber,Electrician,Dentist) rather than plainLocalBusiness. If several apply, you can give@typeas an array. Google notes thatadditionalTypeisn't supported. - Google does not guarantee that structured data will produce any special display in search.
2. A complete example (Durban plumber, fictional)
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Plumber",
"name": "Example Plumbing Durban",
"url": "https://www.example.co.za/",
"telephone": "+27315550123",
"image": "https://www.example.co.za/images/van.jpg",
"address": {
"@type": "PostalAddress",
"streetAddress": "12 Example Road",
"addressLocality": "Pinetown",
"addressRegion": "KwaZulu-Natal",
"postalCode": "3610",
"addressCountry": "ZA"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": -29.81234,
"longitude": 30.85678
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "08:00",
"closes": "17:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Saturday",
"opens": "08:00",
"closes": "12:00"
}
],
"priceRange": "R500-R2500",
"sameAs": [
"https://www.facebook.com/example",
"https://www.linkedin.com/company/example"
]
}
</script>
The business, address and numbers are made up. Replace every value with your own, and test before deploying (see step 5).
3. South Africa-specific details
Phone numbers. Google asks for a telephone that includes the country and area code. For a South African number written locally as 031 555 0123, drop the leading 0 and add +27: +27315550123. The same goes for mobile numbers: 082 ... becomes +2782.... Use the same number that appears on the page and on your Business Profile.
Country code. Use the two-letter ISO code ZA in addressCountry, not "RSA" or "SA".
Province and suburb. Put the province in addressRegion (KwaZulu-Natal, Gauteng, Western Cape...) and the town or suburb people actually search for in addressLocality. South African postal codes are four digits. Write them exactly as they appear on the site and the Business Profile.
Coordinates. If you include geo, Google wants at least five decimal places for latitude and longitude. South African latitudes are negative (southern hemisphere), and that sign is easy to lose when you copy coordinates around.
Price range. priceRange is free text and has to stay under 100 characters. A rand range such as R500-R2500 is clearer to readers than $$.
Hours. Use 24-hour times ("08:00", "17:00"). To mark a day as closed, Google's docs say to set both opens and closes to "00:00". You can also leave the day out.
4. Service-area businesses (you go to the customer)
Many SA businesses, such as plumbers, electricians, cleaners and consultants working from home, hide their street address on Google Business Profile and show a service area instead.
The rule in Google's general structured data guidelines is that markup should describe content that's visible to users on the page. So:
- If the address isn't shown on your site, don't put a full street address in the markup just to "help SEO". At most, use the locality, region, postal code and country you actually show.
- Schema.org has an
areaServedproperty for listing the areas you cover. It's valid schema.org, but it isn't in Google's list of supported LocalBusiness properties, so treat it as context, not as a ranking lever.
5. Things to leave out
-
Review stars about your own business. Since 2019 Google hasn't shown review rich results for
LocalBusinessorOrganizationwhen the business controls the reviews, which includes reviews embedded through a third-party widget (Google Search Central blog). Marking up your own testimonials won't get you stars. - Keyword-stuffed names. Use the real business name. "Example Plumbing | 24/7 Emergency Plumber Durban North" isn't the business name, and it doesn't match your signage or your Business Profile.
- One block listing every city you'd like to rank in. Mark up each real location on the page about that location. A city you merely serve isn't a branch.
6. Test, deploy, check
- Paste the code or URL into Google's Rich Results Test and fix any critical errors.
- Also run it through the Schema Markup Validator to catch schema.org-level issues.
- Deploy, then use URL Inspection in Search Console to check that Google can see the rendered markup (for example, that it isn't blocked by robots.txt or added by a script Google can't run).
- Re-check whenever the phone number, address or hours change. Stale markup that disagrees with your Business Profile is worse than no markup.
Wrap-up
LocalBusiness markup won't rank a site by itself. What it does is state your business details in a machine-readable form, so they're consistent with your page and your Google Business Profile. Keep it short, accurate and specific.
Disclosure: I work with Nexus SEO, a Durban-based SEO agency, and we set up this kind of markup for South African business sites. The example above is fictional, and everything in this post is based on Google's and schema.org's public documentation linked above.
Top comments (0)