squirrelscan
GitHub

One organization, or sixty? Entities declared without an @id

Your site declares the same organization on every page with nothing to say they are one thing. A search engine reading 60 pages sees 60 organizations.

Why an @id is the whole game

Structured data is not a set of per-page annotations. It is a graph, and a graph needs identifiers. When your organization block appears on sixty pages with no @id, a search engine has sixty declarations and no statement that they describe one thing. Nothing accumulates: not your reviews, not your sameAs profiles, not the authority of the articles you published.

The markup validates. Rich Results Test is happy with it. And the site still gets none of the benefit of having it, because there is no entity for the benefit to attach to.

An @id costs one line and fixes it permanently. It is an arbitrary string that happens to look like a URL, it does not need to resolve, and it only has to be identical everywhere.

What squirrel checks

The rule runs once per crawl, reads the entity map rather than the pages, and emits a single check named entity-identity.

  • Skipped with the message No entity map was built for this audit and the reason entity-map-unavailable when the run produced no map. This is not the same as a site with no structured data, and the rule refuses to conflate them: passing here would assert it had checked something it never looked at.
  • Reports at info with the message This site declares no JSON-LD entities on any crawled page when the map exists and is empty.
  • Passes with the message Every multi-page identity entity carries an @id.
  • Fails with the message N entities are declared on several pages with no @id, plus (+N more entities) when more matched than are listed. The value names the widest offender as NAME on N pages and the expectation reads one absolute @id per entity, referenced elsewhere.

Only Organization, LocalBusiness, Person and WebSite are judged: these are the types a search engine reconciles across a site. A Product repeated on a category page and a detail page is not a split identity.

An entity on a single page is never reported, whatever its type. With one declaration there is nothing to tie together, so an @id would buy nothing. An entity with no name is not reported either: without a name there is nothing to reconcile it by, and treating every unnamed node as one identity would merge the site’s whole graph.

Findings are capped at 10 items, and the count in the message is always the true total rather than the capped length. Run squirrel entities --problem no-id for the full list.

How to fix it

Give the entity one absolute @id and use it everywhere:

{
  "@type": "Organization",
  "@id": "https://example.com/#organization",
  "name": "Example Ltd",
  "url": "https://example.com/",
  "logo": "https://example.com/logo.png"
}

The fragment is arbitrary. #organization is the convention Yoast uses and there is no reason to differ. What matters is that it is absolute, not a bare #organization, and byte-identical on every page.

Then stop repeating the full block. On every page that merely refers to the organization, emit only the reference:

{ "@type": "Article", "publisher": { "@id": "https://example.com/#organization" } }

Declare the full block once per page in a @graph, or on the home page alone if every other page can reach it. See fixing structured data identity for the exact shape in Yoast, Rank Math, Next.js and Astro.

Rule IDschema/entity-identity
CategoryStructured Data
ScopeSite-wide
Severityerror
Weight6/10

Enable / disable

Disable this rule

[rules]
disable = ["schema/entity-identity"]

Disable all Structured Data rules

[rules]
disable = ["schema/*"]

Enable only this rule

[rules]
enable = ["schema/entity-identity"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

For one run without editing the config: squirrel audit https://example.com --rule-include schema/entity-identity.

Entity findings are site-wide and ship in every audit, next to the per-page structured data rules. See Fix SEO issues with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com, then squirrel entities to see the graph the finding came from. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close