Semantics.rs
Semantics.rs/SEO/Schema markup
Structured data

Schema markup: connect real entities, do not invent signal.

JSON-LD gives explicit information about the content of a page and can make certain rich results possible. It does not guarantee ranking, and markup that does not match the visible content may simply be ignored.

Author: Precise Search SEO · Published and checked:
On this page
  1. One block or several?
  2. Which nodes we connect
  3. A cohesive graph in practice
  4. How identifiers are written
  5. Which types are used, and when
  6. Connecting an entity to external sources
  7. The same entity across several domains
  8. Mistakes we see most often
  9. How it is validated
  10. Implementation order on a new site

Does there have to be only one script block?

Schema.org allows several blocks and Google can process the supported formats. A single cohesive @graph is our maintenance rule, not a Google requirement: it is easier to track stable @id references and to prevent duplicates.

The three rules that matter more than the number of blocks: markup describes the content of the page it sits on; you never add a price, rating, author, image or identity that is not real and verifiable; and you validate syntax with the Schema Markup Validator and eligibility with the Rich Results Test.

Which nodes do we connect?

Types and their function
NodeWhen it is justifiedTypical relation
OrganizationA real organisation is visible on the sitepublisher, provider
Person / ProfilePageThe author is identified and has a visible biographyauthor, mainEntity
WebPage / ArticleThe page and the article have distinct rolesmainEntityOfPage
ServiceThe service is genuinely described and availableprovider, areaServed
BreadcrumbListA clear URL hierarchy existsWebPage.breadcrumb
Diagram of a JSON-LD graph: Organization, WebSite, WebPage, Article, BreadcrumbList and ImageObject connected by arrows labelled publisher, isPartOf, mainEntity, mainEntityOfPage, author and logo
The same nodes as the table, shown as a graph — every arrow is a reference to a stable @id, not a repeated object.

What does a cohesive graph look like in practice?

Instead of every block repeating the same organisation data, one @graph defines each entity exactly once and routes all further references through a stable @id.

The difference is easiest to see in an example. This is a common pattern that creates duplicates:

{
  "@context": "https://schema.org",
  "@type": "Article",
  "publisher": {
    "@type": "Organization",
    "name": "Example Ltd",
    "logo": "https://example.com/logo.png"
  }
}

If that object is repeated on every page, each copy is a separate, unconnected description. When one detail changes you have to change it everywhere, and you will miss one. The cohesive version looks like this:

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Example Ltd",
      "url": "https://example.com/",
      "logo": { "@id": "https://example.com/#logo" }
    },
    {
      "@type": "ImageObject",
      "@id": "https://example.com/#logo",
      "contentUrl": "https://example.com/logo.png",
      "width": 512,
      "height": 512
    },
    {
      "@type": "Article",
      "@id": "https://example.com/article/#article",
      "headline": "Article title",
      "publisher": { "@id": "https://example.com/#organization" },
      "mainEntityOfPage": { "@id": "https://example.com/article/#webpage" }
    }
  ]
}

The organisation is described once. The logo is a full ImageObject with dimensions rather than a bare URL. The article is tied to its page and to its publisher by reference, not by copy.

How are identifiers written?

An @id must be an absolute URL with a fragment that never changes. The fragment names the role, not the content.

The naming convention we use
EntityPatternWhy
Organisationhttps://domain.com/#organizationExists once for the whole site, so it lives at the root
Websitehttps://domain.com/#websiteLikewise, one per domain
Pagehttps://domain.com/path/#webpageTied to a specific URL
Articlehttps://domain.com/path/#articleSeparate from the page because it has a different role
Imagehttps://domain.com/path/#img-nameThe suffix distinguishes several images on one page

A fragment must not contain a date, a version or a title. #article-2026-august breaks the moment the text is updated, and every change to an @id severs all references pointing at it.

Which types are most used, and when?

You choose the type according to what the page genuinely is, not according to the rich result you would like. The wrong type is a more common problem than a missing type.

The types we implement most often
TypeWhen it is justifiedRequired alongside it
LocalBusinessA physical location a visitor can visit or calladdress, telephone, openingHoursSpecification
ProductA specific product with a price and availabilityoffers with price, priceCurrency, availability
ServiceA service that is provided, with no inventoryprovider, areaServed, serviceType
HowToA procedure with clear steps the reader performsstep as an array of HowToStep nodes
EventAn event with a date and a placestartDate, location, eventAttendanceMode
JobPostingAn active job advertisementdatePosted, validThrough, hiringOrganization
DatasetA dataset that can be downloaded or querieddistribution, license, creator

The most frequent error in this table is Product on a page that describes a service. If there is no stock, no shipping and no returns, it is a Service. The second is LocalBusiness on a site with no physical location — an aggregator or an online-only service does not belong there.

How is an entity connected to external sources?

sameAs connects your entity to its description on sources the search engine already knows. It is the most direct way of saying “this entity is that entity”, instead of relying on name matching.

Name matching is unreliable. “Precise Search SEO” is distinctive, but “Delta” or “Metro” are not. Where a stable external identifier exists, the connection stops being guesswork.

{
  "@type": "Organization",
  "@id": "https://example.com/#organization",
  "name": "Example Ltd",
  "sameAs": [
    "https://www.wikidata.org/wiki/Q00000000",
    "https://en.wikipedia.org/wiki/Example",
    "https://www.linkedin.com/company/example",
    "https://www.crunchbase.com/organization/example"
  ]
}
How much weight each source carries
SourceRole
WikidataStrongest, because it is machine-readable and has a stable identifier
WikipediaStrong, but depends on editorial notability criteria
Official registers and databasesUseful for legal entities; they confirm the entity exists
Social media profilesWeaker, but useful when stronger sources are unavailable

Limit: sameAs does not create an entity in the Google Knowledge Graph and does not guarantee a panel. It connects what already exists. Listing a profile that does not belong to your organisation is inaccurate data, not a shortcut.

The same principle applies to authors, with one extra obligation: a Person node only makes sense when the author has a visible biography on the site and verifiable presence off it. On this site we removed the Person node for that reason and attached all attribution to the organisation — one verifiable entity is stronger than two weak ones.

What if the same entity exists on several domains?

One entity must have one primary @id, on the domain that is its canonical home. Other domains reference that same identifier rather than defining their own copy.

The situation is common: an agency has its own site, a client project and a profile on a third-party platform. If each defines its own Organization node with its own @id, you end up with three entities instead of one.

// On the secondary domain — a reference, not a new definition
{
  "@type": "WebPage",
  "@id": "https://second-domain.com/page/#webpage",
  "publisher": { "@id": "https://primary-domain.com/#organization" }
}

In addition, both domains should list one another in the sameAs array of the primary entity. The connection is then bidirectional and does not depend on the search engine matching two names on its own.

Which mistakes do we see most often?

Common mistakes and their consequence
MistakeConsequenceFix
Markup describes content that is not visible on the pageGoogle may ignore the markup or apply an actionRemove anything the reader cannot see
aggregateRating without real reviewsA breach of the structured data guidelinesOmit it until reviews exist
The same @id on two different pagesTwo documents claim to be the same entityTie the @id to the page’s canonical URL
image as a bare stringDimensions, licence and authorship are lostUse a full ImageObject node
FAQ schema with no visible FAQMarkup and content do not matchMark up only questions that appear on the page
Several blocks describing the same organisationConflicting data about one entityMerge them into a single @graph
Confusing FAQPage with QAPageThe markup describes something the page is notFAQPage for questions the site owner answers; QAPage for a user question with user answers

How is it validated?

  1. Schema Markup Validator for syntax and graph structure. It reports errors Google does not have to report.
  2. Rich Results Test for eligibility for specific displays. Eligibility is not a guarantee of display.
  3. Search Console reports for the state of the whole site over time.
  4. A manual check that every value in the markup also exists in the visible content. No tool does this step for you.

The order matters: the validator comes first, because a syntax error means every other tool is reading an incomplete graph and returning misleading results.

Implementation order on a new site

  1. Organisation and website. Two nodes with stable @id values at the domain root. Everything else attaches to them later.
  2. The logo as a full ImageObject with dimensions, not as a string.
  3. Page and article per document, with the mainEntityOfPage relation in both directions.
  4. The path as a BreadcrumbList with consecutive positions.
  5. The business-specific typeService, Product or LocalBusiness — only once the first four are stable.
  6. sameAs references last, once the external profiles genuinely exist.
  7. FAQ and images only where the visible content is already there.

The order is not arbitrary. Each step references the previous one, so skipping ahead means changing @id values later — and every such change severs the references pointing at them.

Primary sources: Google: introduction to structured data, Google: structured data general guidelines and the Schema.org vocabulary.

Frequently asked questions

Does schema markup improve rankings directly?

Google uses it to understand content better and for eligibility for certain rich results. Eligibility is not a guarantee of display, and a direct ranking effect is not documented.

What happens if the markup describes something not visible on the page?

Google may ignore that markup and, in more serious cases, apply a manual action. The rule is that every value in the markup also exists in the visible content.

Can I add aggregateRating if I have no reviews?

No. A rating without real, verifiable reviews breaches Google's structured data guidelines. Leave the node out until reviews exist.

How many script blocks may a page have?

Schema.org allows several and Google processes them. A single cohesive @graph is our choice for maintenance reasons — it is easier to track @id references and prevent duplicates.