Entity-first indexing is a useful operating model for modern SEO, but it should not be read as a literal switch where Google’s APIs override the ranking system. Google’s public systems still use many signals. The practical point is sharper: keyword density is too weak to describe expertise, while entity coverage, entity disambiguation, source consistency, structured data, and internal relationship graphs are much closer to how search systems understand topics.
If your page says “returns software” twenty times but never connects that term to reverse logistics, refund workflows, return merchandise authorization, carrier labels, Shopify, WooCommerce, customer service, and post-purchase retention, it looks thin from an entity perspective. If your page uses fewer repeated keywords but clearly defines the entities, relationships, evidence, and page role in the site’s topical graph, it is easier for a machine system to classify.
The Entity-First Model
A traditional keyword-first page asks: which query do we want to rank for, and how often should the page mention it? An entity-first page asks: which real-world concepts does this page cover, how confidently can a parser identify them, how are they connected to other known entities, and where does this page sit inside the site’s knowledge map?
Google Cloud Natural Language can extract entities and salience scores from text. The Knowledge Graph Search API can return entities from Google’s Knowledge Graph for a query. These are not ranking APIs, but they are excellent diagnostic tools. If Google’s NLP systems cannot consistently identify the core entities in your content, that is a warning sign for any SEO program that depends on topical authority.

Build A Stable Entity Inventory
Start by creating an entity inventory for each topic cluster. For an ecommerce SEO cluster, that inventory might include Shopify, WooCommerce, Amazon Marketplace, structured data, Product schema, Merchant Center, Core Web Vitals, checkout, return policy, shipping, inventory management, customer reviews, price, availability, and organization identity.
Every entity should have a local canonical URL, a preferred label, aliases, a type, and external identifiers when appropriate. For public concepts, add Wikidata and Wikipedia references if they are genuinely relevant. For your brand, product, service, or proprietary category, use a stable site URL as the canonical identity and avoid pretending that every internal concept has an authoritative external entity.
Use sameAs Without Turning It Into Spam
The sameAs property is most useful when it clarifies identity. It should point to profiles, reference pages, or authoritative IDs for the same entity, not loosely related articles. A page about Shopify can reference Shopify’s public entity pages. A page about your own agency should reference your official profiles and organization identifiers, not every directory listing on the internet.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"@id": "https://www.example.com/guides/shopify-seo#article",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://www.example.com/guides/shopify-seo"
},
"headline": "Shopify SEO Guide",
"about": [
{
"@type": "SoftwareApplication",
"@id": "https://www.example.com/entities/shopify#entity",
"name": "Shopify",
"sameAs": [
"https://www.wikidata.org/wiki/Q181257",
"https://en.wikipedia.org/wiki/Shopify"
]
},
{
"@type": "Thing",
"@id": "https://www.example.com/entities/search-engine-optimization#entity",
"name": "Search engine optimization",
"sameAs": [
"https://www.wikidata.org/wiki/Q180711",
"https://en.wikipedia.org/wiki/Search_engine_optimization"
]
}
]
}
</script>
@id Canonicalization: The Part Most Sites Miss
The @id value is how you consolidate an entity across pages. If your homepage Organization schema uses one @id, your About page uses another, and your author pages invent a third, you have made identity resolution harder than it needs to be. Use stable fragment identifiers such as https://www.example.com/#organization, https://www.example.com/#website, and https://www.example.com/entities/shopify#entity.
The rule is simple: one entity, one canonical @id. Use that ID wherever the entity appears. Article schema, Product schema, BreadcrumbList, FAQPage, Organization, Person, and WebSite nodes can all reference shared IDs. This creates a clean internal knowledge graph that parsers can merge without guessing.

Extract Entity Salience With Python
The following script uses Google Cloud Natural Language to extract entity names, types, salience scores, and linked metadata from your own content. You need Google Cloud credentials configured locally before running it.
from pathlib import Path
from google.cloud import language_v1
client = language_v1.LanguageServiceClient()
def extract_entities(path: str):
text = Path(path).read_text(encoding="utf-8")
doc = language_v1.Document(
content=text,
type_=language_v1.Document.Type.HTML
)
response = client.analyze_entities(
request={
"document": doc,
"encoding_type": language_v1.EncodingType.UTF8,
}
)
rows = []
for entity in response.entities:
rows.append({
"name": entity.name,
"type": language_v1.Entity.Type(entity.type_).name,
"salience": round(entity.salience, 4),
"metadata": dict(entity.metadata),
"mentions": len(entity.mentions),
})
return sorted(rows, key=lambda row: row["salience"], reverse=True)
for row in extract_entities("article.html")[:25]:
print(row)
Salience is not a ranking score. Treat it as a parser visibility score. If the article is meant to be about ecommerce payment processing and the highest-salience entities are only “business,” “customers,” and “tools,” the content is probably too generic. If the core entities appear but important adjacent entities are missing, the article may need more complete coverage.
Map Competitor Entity Gaps
Entity gap analysis is more useful than a phrase-frequency gap. Collect your URL and several ranking competitor URLs. Extract visible content. Run entity extraction on each document. Normalize names and entity IDs. Then compare which entities competitors cover that your article does not, and which entities you cover with stronger depth.
import csv
from collections import defaultdict
def load_entities(csv_path):
by_url = defaultdict(dict)
with open(csv_path, newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
key = row.get("mid") or row["name"].lower()
by_url[row["url"]][key] = {
"name": row["name"],
"salience": float(row["salience"]),
"type": row["type"],
}
return by_url
def entity_gaps(entities_by_url, target_url, min_competitors=2):
target = entities_by_url[target_url]
competitor_counts = defaultdict(int)
competitor_names = {}
for url, entities in entities_by_url.items():
if url == target_url:
continue
for key, data in entities.items():
competitor_counts[key] += 1
competitor_names[key] = data["name"]
gaps = []
for key, count in competitor_counts.items():
if count >= min_competitors and key not in target:
gaps.append((competitor_names[key], count))
return sorted(gaps, key=lambda item: item[1], reverse=True)
entities = load_entities("entity_export.csv")
for name, count in entity_gaps(entities, "https://example.com/target-page"):
print(f"{name}: covered by {count} competitors")
Internal Links Should Reinforce Relationships
Anchor text still matters, but an entity graph gives you a better linking rule. Link from a broad entity page to sub-entity pages. Link from software comparisons to pricing guides, fee calculators, integration guides, migration guides, and operational checklists. Link from evidence pages back to entity hubs. The goal is not to stuff exact-match anchors. The goal is to make relationships explicit.
For example, an article about ecommerce payment processing should connect to guides about payment processing fees in Canada, security for small stores, Shopify fees, and Amazon versus Shopify channel strategy. That network tells a clearer topical story than repeating one anchor phrase across every page.

A Practical Entity Workflow
Use this workflow for every major topic cluster. First, define the target entity set. Second, write the page naturally with evidence, examples, definitions, and adjacent concepts. Third, run NLP extraction and inspect salience. Fourth, add or revise sections where important entities are missing. Fifth, add JSON-LD with stable @id nodes and honest sameAs links. Sixth, build internal links that reflect entity relationships. Seventh, revisit the page after Search Console data shows the actual query set.
This is not a replacement for useful writing. It is a way to make useful writing easier for machines to understand. The best page still wins by satisfying the searcher, but entity clarity helps search systems decide what the page is about, how it relates to the rest of the site, and whether the site has real topical depth.
Query The Knowledge Graph For Disambiguation
The Knowledge Graph Search API is useful when a term has multiple meanings. “Make” can mean an automation platform, a verb, a magazine, or manufacturing. “Shopify” is usually unambiguous. Before adding external identifiers, confirm that the entity result matches the topic, type, description, and canonical page you intend.
import os
import requests
API_KEY = os.environ["GOOGLE_KG_API_KEY"]
def kg_candidates(query, limit=5):
response = requests.get(
"https://kgsearch.googleapis.com/v1/entities:search",
params={
"query": query,
"key": API_KEY,
"limit": limit,
"indent": True,
},
timeout=20,
)
response.raise_for_status()
for item in response.json().get("itemListElement", []):
result = item.get("result", {})
yield {
"name": result.get("name"),
"id": result.get("@id"),
"types": result.get("@type", []),
"description": result.get("description"),
"score": item.get("resultScore"),
}
for candidate in kg_candidates("Shopify ecommerce platform"):
print(candidate)
Do not blindly map every candidate. Store a human-approved entity ID when the match is important. For internal editorial workflows, keep a small entity registry in a spreadsheet, database, or CMS field: preferred label, aliases, internal entity URL, Wikidata URL, Wikipedia URL, Knowledge Graph ID when available, and notes about ambiguity.
Entity QA Before Publishing
Before publishing, run a simple QA pass. Does the title define the primary entity? Does the introduction mention the entity and its context naturally? Do H2 sections cover sub-entities rather than vague advice? Does the JSON-LD reuse stable @id values? Are external sameAs links truly the same entity? Are internal links connecting parent, child, and adjacent topics?
The most common failure is over-linking to famous entities while ignoring the site’s own entities. A Shopify article should reference Shopify, but it should also define your local ecommerce platform hub, Shopify fee calculator, migration guide, app stack guide, and related operational pages. That is how a site builds its own graph instead of renting all meaning from Wikipedia.
Sources
- Google Cloud Natural Language entity analysis.
- Google Knowledge Graph Search API documentation.
- Google Search Central structured data introduction.
- Schema.org sameAs.
- Schema.org Article.
Last Reviewed
Last reviewed: July 27, 2026.
Affiliate Disclosure
This site may earn commissions from links at no extra cost to the reader.









