Home/ The SEO and GEO Guide/ Guide
- Give every important entity (organisation, website, person, product) a stable @id, usually the canonical URL plus a fragment such as #organization.
- Reference entities by @id instead of repeating them as plain text strings, so authors, publishers and brands resolve to one node.
- Do not assume search engines follow an @id to another page. Include the essentials, such as name and url, wherever a node appears.
- Markup must describe what is visible on the page. A graph is a description, not a wish list.
- Test the parsed graph with the Schema Markup Validator, not just the Rich Results Test.
Most sites add structured data one block at a time: an Organization on the homepage, an Article on each blog post, a Product on each product page. Each block is valid on its own, but nothing says that the publisher of the article, the brand on the product and the organisation on the homepage are the same thing. A connected schema graph fixes that. Every entity gets a stable identifier, and the blocks point at each other, so the markup reads as one joined-up description of who you are, what you publish and who wrote it.
Why connect your structured data
Disconnected markup forces machines to guess. If an article lists its author as the text string "Jane Smith" and the about page describes a Person called Jane Smith, a parser has to decide whether those are the same person, and it may not bother. With a graph, the article's author is a reference to a node that also carries a job title, an employer, a photo and links to official profiles elsewhere. The relationship is stated, not inferred.
Be realistic about the payoff. Google does not award a ranking boost for tidy graphs, and rich result eligibility depends on the specific features listed in its search gallery. The value is disambiguation: making it easy for search engines, and the systems built on them, to connect your pages, people and brand to the right entities.
How @id and @graph work
JSON-LD, defined in the W3C JSON-LD 1.1 specification, lets any node carry an @id. It is an identifier, not a link for users to follow, so the usual convention is your canonical URL plus a fragment. Another node can then refer to it with an object containing nothing but that @id. The @graph keyword holds several nodes in one script block, which is far neater than nesting everything.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.example.com/#organization",
"name": "Example Ltd",
"url": "https://www.example.com/",
"logo": "https://www.example.com/logo.png",
"sameAs": ["https://www.linkedin.com/company/example"]
},
{
"@type": "WebSite",
"@id": "https://www.example.com/#website",
"url": "https://www.example.com/",
"publisher": { "@id": "https://www.example.com/#organization" }
},
{
"@type": "Person",
"@id": "https://www.example.com/about/jane#person",
"name": "Jane Smith",
"worksFor": { "@id": "https://www.example.com/#organization" }
},
{
"@type": "Article",
"headline": "Hreflang explained",
"isPartOf": { "@id": "https://www.example.com/#website" },
"author": { "@id": "https://www.example.com/about/jane#person" },
"publisher": { "@id": "https://www.example.com/#organization" }
}
]
}
Designing a graph for a whole site
Think in three layers.
- Site-wide nodes: the Organization (or a more specific type such as ProfessionalService or OnlineStore), the WebSite and the logo. These should carry identical @id values on every page.
- Page nodes: a WebPage, or a subtype such as AboutPage or CollectionPage, that is isPartOf the WebSite and carries a breadcrumb. Use mainEntity or about to say what the page is really describing.
- Content nodes: the Article, Product, Event, Service or Person the page is about, linked back to the site-wide nodes through author, publisher, brand, provider or worksFor.
One practical caution: search engines generally process markup page by page. Do not rely on a crawler fetching another URL to resolve a bare @id reference. Put the full Organization node on your homepage and about page, and on other pages include at least its name and url alongside the @id. It costs a few bytes and removes the ambiguity.
Properties that do the linking
- publisher, author, creator connect content to people and organisations.
- worksFor, founder, employee, memberOf connect people to organisations.
- isPartOf, hasPart, mainEntityOfPage connect pages, sites and content.
- about, mentions, mainEntity say what a page or article is about, and can point at Wikidata or Wikipedia URLs for topics.
- brand, manufacturer, provider, offers link products and services to the businesses behind them.
- sameAs connects your node to the same entity elsewhere: Wikidata, Wikipedia, LinkedIn, Companies House, official social profiles.
- identifier carries hard IDs such as a company number, ISBN or GTIN.
Implementation in practice
- Popular WordPress SEO plugins already output an @graph with @id values. Extend their graph through the plugin's filters instead of adding a second Organization block alongside it.
- Headless and custom builds should generate the graph from CMS data at render time, so a renamed author or a new logo updates everywhere at once.
- Tag manager injection works for Google, which renders JavaScript, but most AI crawlers do not run scripts. Server-side output is safer.
- Keep @id values boring and permanent. They do not need to resolve to a page, but they must never change with a redesign or a CMS move.
- Document the IDs. A one-page list of your canonical @id values stops each new template inventing its own.
Common mistakes
- Different @id values for the same organisation on different templates, often down to http and https or trailing slash differences.
- Two Organization nodes with conflicting names or logos, one from a plugin and one hand-coded.
- Markup describing things the page does not show, which breaks Google's structured data policies and can lead to a manual action.
- Using @id as a replacement for url. You still need the url property.
- sameAs links to profiles that are not yours, are broken or describe a namesake.
- Enormous knowsAbout lists that are really keyword stuffing in disguise.
How to test
- The Schema Markup Validator shows the parsed graph, including whether references resolve within the page.
- The Rich Results Test checks only the features Google supports, so a clean result there says nothing about the rest of the graph.
- Crawl the site with structured data extraction enabled and compare @id values across templates. Site-wide nodes should be identical everywhere.
- View source to confirm the markup is in the raw HTML, not added later by scripts.
The GEO angle
AI assistants answer questions about entities: who runs this company, what does it sell, who wrote this guide. Bing and Google feed structured data into the indexes that ground those answers, and a graph stating "this article, by this person, who works for this organisation, which is the same as this Wikidata item" leaves very little room for confusion with a competitor or a namesake. Direct evidence that language models read JSON-LD at answer time is thin, so treat the graph as one strong, consistent signal among several, alongside a clear About page and the third-party profiles it points to.
Further reading
Related guides
