Technical & Structure · 7 min read · September 24, 2026 · Hafsa Tariq, gaash.ai
Setting up schema.org markup correctly: where it goes, how it is generated, and how to keep it true
Setting up schema.org markup correctly takes four decisions: what the markup says, where the JSON-LD goes, how it gets into the page, and who keeps it true. Write the business's facts once, from one source; put one JSON-LD graph in the HTML the server sends; check that no plugin or builder adds a second, conflicting business; then test what the page states against what a visitor sees. Most broken markup fails the third or fourth decision, not the first.
Decide what the markup says before deciding where it goes
Markup is a second copy of facts the page already states, so it starts with the facts: the business's name as it appears on the sign, one address, one main phone number, the hours by day, the area served, and the services by their plain names. Write them in one place, a settings page in your site's admin or a short document your web person keeps, and let every page and every block of markup take them from there. A fact written twice drifts; a fact written once changes everywhere at the same time.
Which schema.org types to use for the business and its pages is in structured data for AI, and how the nodes point at one another with @id is in building an entity. This article is about the setup around them.
Where the JSON-LD goes
One script element of type application/ld+json, in the head or the body of the page. Google's introduction to structured data recommends JSON-LD, the format defined in the W3C's JSON-LD specification, and it can sit apart from the visible HTML while still describing it. One block holding a graph of nodes, each with its own @id, is easier to keep consistent than several blocks written by different tools.
| Page | Nodes it carries | Why |
|---|---|---|
| Every page, or at least the homepage and contact page | The business node (the most specific LocalBusiness type that fits), with name, address, telephone and hours | Any page an assistant lands on can say whose it is |
| Each service page | A Service node whose provider points at the business node's @id, with an Offer where a price is shown | The service and its price belong to the page that states them |
| Each article | An Article or BlogPosting node with its author, dates and the business as publisher | A dated, attributed page, stated as such |
| Pages below the homepage | A BreadcrumbList | The page's place on the site, in order |
| Each location, if there are several | One business node per location, each with its own address, phone and hours | Several places, stated as several places |
Written into the page, or injected by a script
Put the block in the HTML your server sends, not in a script that adds it after the page loads. Google renders JavaScript, but its JavaScript documentation describes rendering as a separate step that can come later than the crawl, and a crawler that runs no scripts at all receives only the HTML. Markup injected by a tag manager or a widget is markup some of your readers never see.
Check it the way a crawler would. View the page source, not the browser's element inspector, which shows the page after scripts have run, and search it for application/ld+json. If the block is there, it is in the HTML. If it appears only in the inspector, a script put it there.
Builders and plugins: the second business nobody meant to add
Page builders and SEO plugins often add markup on their own: a WebSite node, an Organization node filled from the site title, sometimes a LocalBusiness node with whatever phone number was typed into the plugin's settings a year ago. Add your own block on top and the page can describe two businesses with two phone numbers. Our audit of 9,483 small business websites found the pattern at scale: 17.8% of the sites had no schema.org markup at all, most of the markup the rest carried described the website rather than the business, and a further 13.7% had business markup missing the fields that would make it usable.
- View the source of the homepage and count the
application/ld+jsonblocks, noting which tool wrote each. - List every node of a business type across them, with the name, address and phone each one states.
- Keep one writer for the business node, the plugin or your own block, and switch the other off in its settings rather than deleting its output by hand.
- Fill in the one you keep from the facts source, and check that the page's visible footer states the same values.
- Repeat on a service page and the contact page, because some tools behave differently by template.
Testing: valid is not the same as true
Two kinds of tool answer two different questions. Google's Rich Results Test reports what Google reads for the search features it supports and flags errors against those features' rules. The Schema Markup Validator run by the schema.org project checks a block against the whole vocabulary, including types Google shows nothing for. Use both, and read their reports as statements about syntax and vocabulary.
Neither tool can tell you whether the phone number in the markup is the number that rings. That check is yours: set the block beside the visible page and compare every value. Google's structured data guidelines require markup to describe the visible page and not to mislead, which no validator can confirm for you. After a change goes live, Search Console's reports show over the following weeks whether Google read the markup the way you meant.
Keeping it true when the business changes
Markup goes stale the way a footer does, one change at a time. Hours move with the seasons, a service is dropped, a second location opens, the phone system changes. Make the change in the facts source on the day it happens, let the templates carry it to the page and the markup together, and read one page's source afterward to confirm both changed.
- Remove the Service node for a service you no longer offer, on the day the page comes down.
- Change dateModified on an article only when its words change, not when the template does.
- Add holiday hours as specialOpeningHoursSpecification before the holiday, and take them out after it.
- Look at the business node once a quarter against the sign, the phone and the map listing.
What not to mark up
- Anything the page does not show. Markup that states a fact a visitor cannot see is exactly what Google's guidelines rule out.
- Reviews or ratings copied from a platform. Google's review snippet rules say not to aggregate them from other websites, and a business's reviews of itself on its own site earn no stars.
- FAQ markup added only for the rich result, which Google no longer shows for any site. Implementing FAQ schema covers what the markup still does.
- A type that does not exist. Check the type on schema.org before using it; where no type fits exactly, use the nearest parent that does.
Common questions
Do I need a developer to add schema.org markup?
Not always. Many site builders and plugins let you fill in the business details and write the block for you; the work is then to fill them in correctly and turn off any second tool doing the same job. Hand-written blocks need someone who can edit the page template. Either way, the facts have to match the visible page.
Should the markup be on every page?
The business node should be on every page, or at least on the homepage and the contact page, so any page can say whose it is. Nodes about a page itself, such as a Service, an Article or a BreadcrumbList, belong only on that page. One graph per page, with @id links between the nodes, keeps them from repeating the same facts in different words.
Will schema.org markup get my business into AI answers?
Nobody can promise that. Google's page on AI features says no special markup is needed for its AI results, and no assistant's operator documents how markup is weighed. What correct markup does is state the business's facts precisely, in a form any parser reads, matching what the page says. That removes a source of doubt; it does not buy a place.
Which validator should I trust?
Both, for different things. Google's Rich Results Test tells you what Google reads for the features it supports; the Schema Markup Validator checks the block against the whole schema.org vocabulary. Neither checks whether the facts are true, so the last test is always yours: the markup beside the page, value by value.
Sources
The markup figures are this site's own, from the audit named below, for all 40 trades in it. What Google recommends and requires is from its own pages, linked where each is used.
Sources: our audit of 9,483 small-business sites, with its method · Google, introduction to structured data · Google, structured data general guidelines · Google, JavaScript SEO basics · W3C, JSON-LD 1.1 · Google Search Central, documentation updates
Read on