

The @id attribute in JSON-LD structured data is the foundation for creating clear and maintainable internal entity relationships with your schema markup. To understand how to use it effectively, we must start with its fundamental role in JSON-LD and build up to implementation patterns.
In JSON-LD structured data, @id creates unique identifiers for nodes in your data graph. Unlike the Schema.org properties url and identifier that communicate information to search engines, @id is an internal reference system within your JSON-LD markup. This distinction is important because it affects how we use @id in practice.
<div class="post-note">TL;DR: @id gives a schema node a stable, unique identifier (usually a URL or URL fragment) that can be referenced elsewhere. This takes isolated bits of JSON‑LD and turns them into a connected data graph, the core principle of linked data.</div>
Let's look at a basic implementation:
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example Company",
"url": "https://example.com"
}
The @id creates a reference point for this organization entity in this example. The value looks like a URL, but it doesn't need to point to a webpage - it's just an identifier. We commonly use URL-style formatting because it helps maintain uniqueness and provides a logical structure for our identifiers.
When we define an entity with an @id, we can reference it elsewhere in our structured data. This creates explicit connections in our data graph. Here's how that works:
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "About Us",
"publisher": {
"@id": "https://example.com/#organization",
"url": "https://example.com"
}
}
When a JSON-LD parser processes these snippets, it recognizes that the WebPage's publisher refers to the same entity defined in our first example. This connection is precise and unambiguous, thanks to the matching @id values. 💪
Here's another way to visualize it:
@id = url + unique name
//what I do
@id = {url for @type entity home} + #{schema-type}
@id = https://example.com/#organization
Here's where things get fun - and where many implementations go wrong. We need to understand three key concepts about scope:
<div class="post-note-cute"><b>Note:</b> Just like search engines, publicly available schema.org markup testing tools—like Google Rich Results Tester and Schema.org Validation Tool—analyze on a page by page basis. They will not find or flag @id error. Even crawling tools like Screaming Frog will not catch these; even if you have all of the Structured data settings turned on. It's up to you to implement properly and be confident about it!. You got this. 🫡</div>
Let's jump back in.
To properly reference entities across pages, you must use both @id and url properties together. Here's how that works:
First, define your entity with both properties:
{
"@context": "https://schema.org",
"@type": "Product",
"@id": "https://example.com/products/blue-shirt#product",
"url": "https://example.com/products/blue-shirt",
"name": "Classic Blue Shirt"
}
Then, when referencing this product from another page, you need to include both properties again:
{
"@type": "Product",
"@id": "https://example.com/products/blue-shirt#product",
"url": "https://example.com/products/blue-shirt"
}
The @id creates the unique identifier, while the url property tells search engines where to find this entity's home. You need both to create proper cross-page connections.
When referencing this product from another page:
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Featured Products",
"mainEntity": {
"@id": "https://example.com/products/blue-shirt#product",
"url": "https://example.com/products/blue-shirt"
}
}
We include the @id for consistent identification and the url property to tell search engines where to find the content. This pattern ensures each page can stand alone while maintaining consistent entity identification across your site.
Disambiguation is important to consider no matter what. Structured data gives us the ability to do this through the combination of @id for internal references and sameAs for connecting to authoritative sources across the web. Here's what this looks like in practice:
{
"@context": "https://schema.org",
"@type": "Article",
"@id": "https://example.com/blog/seo-tips#article",
"author": [
{
"@type": "Person",
"@id": "https://example.com/team/jane-doe#person",
"name": "Jane Doe",
"url": "https://example.com/team/jane-doe",
"sameAs": [
"https://www.linkedin.com/in/jane-doe",
"https://en.wikipedia.org/wiki/Jane_Doe",
"https://g.co/kgs/JWFoNWi"
]
},
{
"@type": "Person",
"@id": "https://example.com/team/john-smith#person",
"name": "John Smith",
"url": "https://example.com/team/john-smith",
"sameAs": [
"https://www.linkedin.com/in/john-smith",
"https://en.wikipedia.org/wiki/John_Smith_(author)",
"https://g.co/kgs/Mx7yP9"
]
}
]
}
The @id property creates unique references within your structured data, while sameAs links connect to authoritative external profiles. This combination helps search engines confidently identify who's who, even when dealing with common names or multiple authors.
You might just influence a knowledge panel in Google Search with these practices.
For complex pages with multiple related entities and @types, the @graph technique helps organize our markup while maintaining clear relationships:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example Company",
},
{
"@type": "WebPage",
"@id": "https://example.com/about#webpage",
"publisher": {
"@id": "https://example.com/#organization"
}
}
]
}
This keeps our markup organized and makes relationships explicit while ensuring all necessary information is on each page.
For connecting to external entities, entity linking through the sameAs property is the preferred approach. While @id and url work together to establish connections within your own website, sameAs helps search engines understand how your entities relate to established entities across the web:
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://example.com/#organization",
"url": "https://example.com",
"sameAs": [
"https://wikipedia.org/wiki/Your_Company",
"https://wikidata.org/entity/Q12345",
"https://twitter.com/YourCompany",
"https://www.linkedin.com/company/your-company"
]
}
Entity linking through sameAs serves a different purpose than internal references with @id/url. While @id/url helps establish connections between your own content, sameAs helps search engines build a broader knowledge graph by connecting your entities to authoritative external sources. This is particularly valuable because:
The sameAs property can point to various types of authoritative sources:
By using entity linking through sameAs alongside your internal @id/url connections, you create a more complete picture of your entities for search engines to understand.Practical Implementation StrategyWhen implementing @id across a site, follow this systematic approach:
Remember that while current search engine processing happens page by page, implementing @id thoughtfully creates structured data that's both maintainable and ready for future developments in how search engines might process connected data.
Always test your implementation using Google's Rich Results Test and.or Schema.org's validator. The Schema.org validator is my preference as it validates more than rich result-eligible types. It also shows how your connected pieces of schema markup work together.
Pay special attention to:
Here are some practical implementation details:
Use your page’s canonical URL plus a hash and a descriptive entity name. For example:
Some people prefer using just a fragment (e.g., "@id": "#product123"), which is resolved against the page URL. Either works, but the full URL plus fragment is often clearer.
<div class="post-note-cute">Note: As of January 2024, Google's examples favor using hashtags for in‑page identifiers.</div>
Descriptive fragments like #organization or #author-jane-doe are more straightforward to debug and understand than generic ones like #id1.
Assign a unique, unchanging @id to each entity and always use that same identifier when referring to it. Avoid using the same @id for different entities to prevent unintended merging.
Treat your @id values as permanent labels. Avoid dynamic components (like timestamps) that change on every page load. Consistency is important—if "Product123" is represented by https://example.com/products/123#item, use that exact string every time.
Since Google processes each page independently, every page's structured data must include all required properties—even if you reference an entity from another page via @id. If necessary, include a minimal duplicate of the entity by including url (or use the @graph technique) to help the page stand independently.
Even though structured data @id linking across pages isn’t automatically merged, traditional HTML links are still recognized. For example, if our Organization has a dedicated page, include an HTML link (e.g., <code><a href="/about-us#organization">Our Organization</a></code>) on relevant pages. This reinforces the connection to search engines and knowledge graph builders.
To connect our internal entity with external authoritative sources (like Wikipedia or Wikidata), use the sameAs property. This helps search engines further disambiguate and consolidate our entity in the global Knowledge Graph.
Run your schema/pages through Google's Rich Results Test or Schema.org's validator. I prefer the Schema.org validator since it validates more than what’s available as a rich result in Google Search.
While search engines currently process structured data page by page, implementing @id consistently creates a foundation for better-organized structured data. The Web Almanac shows growing adoption of JSON-LD (now at 41% of pages), with sophisticated entity relationships becoming more common, especially in ecommerce and local business implementations.The careful use of @id and url properties helps create clear entity relationships that benefit current SEO needs and prepare for future developments in how search engines might process connected data.
<div class=post-note-cute"><p>Follow these practices to be confident your structured data is actionable (for immediate SEO features) and strategically sound for long‑term semantic SEO and AI readiness.</p><p>Happy knowledge graph building!</p></div>
Tell me what's wrong with my homepage schema.org markup, and I'll give you a shoutout in this article. (Hint: I'm not talking about the lack of @graph implementation).
{
"@context": "https://schema.org",
"@type": ["Organization","LocalBusiness"],
"name": "Momentic",
"alternateName":["Momentic®","Momentic SEO","MOMENTIC","Momentic LLC","Momentic Marketing","Momentic Inc.","Momentic Inc","MOMENTIC LLC"],
"legalName":"Momentic, LLC",
"logo": "https://assets-global.website-files.com/6213ddd7bd3eb80dfdbf1d95/62a215921d30e82307ea5f1b_Momentic%20Landscape%20(2022)-p-500.webp",
"image": "https://assets-global.website-files.com/6213ddd7bd3eb80dfdbf1d95/62a215921d30e82307ea5f1b_Momentic%20Landscape%20(2022)-p-500.webp",
"photo":"https://assets-global.website-files.com/6213ddd7bd3eb80dfdbf1d95/629a2e6de39f70f44dcbf99c_Momentic%20Office-p-800.webp",
"@id": "https://momenticmarketing.com/#organization",
"slogan":"Dead set on delivering results.",
"url": "https://momenticmarketing.com/",
"description": "Momentic is an SEO marketing firm that generates long-term, quantifiable growth for their clients.",
"founder":[{
"@type":"Person",
"name": "Tyler Einberger",
"alternateName": "Twin Lull",
"familyName": "Einberger",
"givenName": "Tyler",
"description": "COO of Momentic",
"id": "https://momenticmarketing.com/team/tyler-einberger#person",
"url": "https://momenticmarketing.com/team/tyler-einberger",
"mainEntityOfPage": "https://momenticmarketing.com/team/tyler-einberger",
"image": "https://assets-global.website-files.com/6213ddd7bd3eb8fb93bf1da4/62aca4fdd09d20d370c8d62b_Tyler%20Talking%20Color.png",
"sameAs": [
"https://www.google.com/search?kgmid=/g/11f0ztyxj9",
"https://www.google.com/search?kgmid=/g/11l75w9y_g",
"https://www.google.com/search?kgmid=/g/11hcx8tsrp",
"https://www.wikidata.org/wiki/Q123358916",
"https://twitter.com/web_shredder",
"https://www.crunchbase.com/person/tyler-einberger",
"https://uwm.edu/sce/instructors/tyler-einberger/",
"https://www.youtube.com/channel/UCxg3CGv4QpT5rIQV6rrh9DQ",
"https://www.linkedin.com/in/tyler-einberger",
"https://tylereinberger.com/",
"https://tylereinberger.wordpress.com/",
"https://music.apple.com/sc/artist/twin-lull/1546007568",
"https://www.tiktok.com/music/My-English-6922647194210142209",
"https://open.spotify.com/artist/217ReduBchO4xG62Udd2oS"
],
"jobTitle": "Chief Operations Officer",
"worksFor": {
"@id": "https://momenticmarketing.com/#organization"
}
},
{
"@type":"Person",
"name": "Tony Van Hart",
"familyName": "Van Hart",
"givenName": "Tony",
"description": "CEO of Momentic",
"url": "https://momenticmarketing.com/team/tony-van-hart",
"mainEntityOfPage": "https://momenticmarketing.com/team/tony-van-hart",
"image": "https://assets-global.website-files.com/6213ddd7bd3eb8fb93bf1da4/62b0bef0dbb46258df206926_Tony.png",
"sameAs": [
"https://www.linkedin.com/in/tony-van-hart-2609ba24",
"https://www.instagram.com/tonyyyyy/",
"https://www.crunchbase.com/person/tony-van-hart",
"https://theorg.com/org/momentic/org-chart/tony-van-hart"
],
"jobTitle": "Chief Executive Officer",
"worksFor": {
"@id": "https://momenticmarketing.com/#organization"
}
}
],
"mainEntityOfPage":"https://momenticmarketing.com/",
"telephone" : "+14144889140",
"priceRange": ["$", "$$"],
"address": {
"@type": "PostalAddress",
"streetAddress": "316 N Milwaukee St #350",
"addressLocality": "Milwaukee",
"addressRegion": "WI",
"postalCode": "53202",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 43.0344638,
"longitude": -87.9056667
},
"hasMap":"https://www.google.com/maps/place/Momentic/@43.0344638,-87.9056667,15z/data=!4m6!3m5!1s0x880519a6770691a3:0xd9a2d7728252b777!8m2!3d43.0344638!4d-87.9056667!16s%2Fg%2F11gg9bgn53",
"areaServed": {
"@type": "Country",
"name": "United States",
"sameAs": ["https://en.wikipedia.org/wiki/United_States","https://www.google.com/search?kgmid=/m/09c7w0"]
},
"openingHoursSpecification": {
"@type": "OpeningHoursSpecification",
"dayOfWeek": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday"
],
"opens": "08:00",
"closes": "17:00"
},
"sameAs": [
"https://www.google.com/search?q=Momentic&ludocid=15682333739270190967",
"https://goo.gl/maps/n4GRXhrcrsHGZpXm8",
"https://www.facebook.com/MomenticSEO/",
"https://twitter.com/MomenticSEO",
"https://www.instagram.com/momenticseo/",
"https://www.linkedin.com/company/momentic-seo",
"https://www.crunchbase.com/organization/momentic-677e",
"https://theorg.com/org/momentic",
"https://clutch.co/profile/momentic"
]
}
<div class="post-note-cute"><p><strong>Free IRL Schema.org event in Milwaukee on April 16th!</strong><p>Martha van Berkel, CEO of Schema App, will be presenting live at MKE DMC on April 16, 2025. In this session, we’ll discuss how digital marketers and SEOs can leverage Schema Markup to build a reusable content knowledge graph and help search engines / LLMs understand your content and its connections more accurately.</p> <p>Event details & RSVP here!</p></div>
Here are some helpful and contextually relevant resources I gathered for y'all to help you on your journey.