Structured data is usually treated as a technical afterthought: install a plugin, tick the boxes, move on. That treatment produces markup that is present, syntactically valid and quietly wrong, which is the worst of the three available states.
The more useful framing is that markup is content. It is a second, parallel expression of what the page says, written for a reader that cannot infer, and it should be authored with the same care as the prose it accompanies.
What markup actually does
It removes interpretation. A page that says "open until six" requires a machine to work out which
days, which time zone and which exceptions. An openingHoursSpecification block states it
without ambiguity. That is the entire function: not persuasion, not ranking, disambiguation.
Google's introduction to structured data sets out what it is used for, and the general guidelines set the constraints: the markup must represent the content of the page, must not mislead, and must be visible to users where the guidance requires it.
Three rules that prevent most problems
- Only mark up what is on the page. If the FAQ answers are not visible, do not publish FAQPage markup. If the review is not shown, do not publish an aggregate rating.
- Make it identical to the visible text. Where the visible page says one thing and the markup says another, you have published a contradiction about yourself.
- Maintain it. Prices change, hours change, practitioners leave. Markup that was accurate in 2024 is a false statement in 2026, and nothing on the page reminds anyone it is there.
Automatically generated markup is generated from templates and defaults. It frequently asserts a business type that is wrong, an address that is stale, an aggregate rating pulled from a widget, or an author that is the content management system user account. Read your own markup as text at least once, on each page type. Most clinics have never done this.
The types a clinic actually needs
| Page | Primary type | Also useful |
|---|---|---|
| Homepage | MedicalClinic or LocalBusiness | WebSite, Organization |
| Location page | MedicalClinic per site | PostalAddress, GeoCoordinates, openingHours |
| Treatment page | MedicalWebPage | MedicalProcedure, FAQPage, BreadcrumbList |
| Practitioner page | Physician or Person | worksFor, memberOf, sameAs |
| Article | Article or MedicalWebPage | author, datePublished, dateModified |
Anything beyond that list is usually solving a problem the clinic does not have. Depth in the types you use beats breadth across types you use badly.
Writing it deliberately
Treat each block as a set of claims and check each claim. Is the name exactly the canonical name? Is
the address in the canonical format? Is the phone number the canonical one? Is the specialty accurate
and defensible? Does the opening hours block include the exceptions? Is every URL in
sameAs a record you stand behind?
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "MedicalWebPage",
"@id": "https://example.co.uk/treatments/acne-scarring#page",
"url": "https://example.co.uk/treatments/acne-scarring",
"name": "Acne scarring treatment: what it involves and who it suits",
"description": "How acne scarring is assessed and treated, what recovery looks like and who is not suitable.",
"inLanguage": "en-GB",
"datePublished": "2026-02-10",
"dateModified": "2026-07-30",
"medicalAudience": {
"@type": "MedicalAudience",
"audienceType": "Patient"
},
"specialty": "https://schema.org/Dermatologic",
"publisher": {
"@id": "https://example.co.uk/#clinic"
},
"about": {
"@type": "MedicalCondition",
"name": "Acne scarring"
},
"lastReviewed": "2026-07-30",
"reviewedBy": {
"@type": "Physician",
"name": "Dr Example",
"medicalSpecialty": "https://schema.org/Dermatologic"
}
},
{
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.co.uk/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Treatments",
"item": "https://example.co.uk/treatments"
},
{
"@type": "ListItem",
"position": 3,
"name": "Acne scarring",
"item": "https://example.co.uk/treatments/acne-scarring"
}
]
}
]
}Using stable identifiers
Give the organisation a stable @id, typically a fragment URL on your own domain, and
reference it from other blocks rather than repeating the organisation details on every page. That
makes the graph explicit: one organisation, referenced many times, rather than forty separate
organisation declarations that may drift apart. The
JSON-LD specification defines the
mechanics.
Validating properly
- Parse the JSON. A trailing comma makes the whole block invisible, and it fails silently.
- Run the URL through the Rich Results Test to see what Google can read.
- Run it through the Schema Markup Validator for vocabulary correctness beyond Google's subset.
- Read the block as prose and ask whether every sentence it implies is true.
- Check the Search Console enhancement reports for errors appearing at scale.
Step four is the one that gets skipped and the one that catches real problems, because syntactic validity says nothing about truth.
Your own website
HIGH CONTROL- Every byte a crawler receives, and the speed it arrives at
- The entity claims: name, address, identifiers, sameAs, service list
- Canonical URLs, hreflang if used, and the internal link graph
- Whether the page answers the question it was built to answer
- How the answer is displayed once it leaves your server
- Whether a third party republishes an outdated version of your facts
- Crawl the whole site and compare the URL list against the sitemap
- Validate every JSON-LD block against the Rich Results Test
- Measure field data, not only lab scores, for Core Web Vitals
Aggregate ratings, carefully
Review markup is the area where clinics most often publish something they should not. Aggregate rating markup must reflect reviews that are genuinely about the entity and visible on the page, and must not be self-serving in the ways the guidelines prohibit. Marking up a rating collected on a third-party platform as though it were on your page is a policy problem, not a clever shortcut.
Medical content markup
Where a page carries clinical information, MedicalWebPage is the appropriate type and it supports properties that matter: the specialty, the intended audience, and the aspect of the subject covered. Using it accurately tells a system that the page is clinical content published by a clinical organisation, which is a more precise statement than Article.
Putting it on a schedule
Add markup review to the same cycle as content review. When a page is edited, the markup is checked. Twice a year, every page type is read as text and verified against reality. This costs very little and it prevents the state most clinic sites are in: valid, present, and no longer true.
