Documentation · Site JSON-LD for ExpressionEngine

Structured data for any EE site — and the tools to prove it's valid.

Site JSON-LD pairs a single render tag with a control panel that validates a page, crawls your site, and reports coverage with an actionable fix for every finding. Site-wide defaults come from settings; per-page specifics from the tag.

Add-on version: v1.9.3 ExpressionEngine 7+ Commercial · single-site license

1.How Site JSON-LD works

Search engines read JSON-LD — a block of structured data in your page's <head> — to understand what a page is: an article, a review, a product, a video. Get it right and you're eligible for rich results; get it subtly wrong and you silently aren't.

Site JSON-LD splits the job in two. Site-wide facts — your organization name, logo, social profiles, search URL, a fallback share image — are entered once on the Settings page. Per-page facts — this entry's title, image, author, dates, type — come from one render tag in your template. The add-on assembles both into a single, correctly-nested JSON-LD graph, adds breadcrumbs automatically, and emits it.

And then it checks itself

The control panel doesn't just generate markup — it validates it. Point it at a URL and it fetches the rendered page, extracts the JSON-LD, and checks it against Google's required and recommended fields. Crawl the site for a sample across channels, and read your coverage. Every problem comes with a concrete fix, not a cryptic code.

2.Install & quick start

  1. Buy + download from expressionengine.com/add-ons/site-jsonld.
  2. Extract to system/user/addons/site_jsonld/.
  3. Install via CP → Add-ons → Site JSON-LD → Install.
  4. Fill Settings — organization name, logo, social sameAs URLs, search URL, fallback image.
  5. Add the render tag to your templates' <head> (below), then Validate a live URL from the CP.
{exp:site_jsonld:render
  type="Article"
  title="{title}"
  image="{article_image}"
  author="{author}"
  crumbs="auto"
}

3.Site settings

The Settings page (per site) holds the facts that don't change page to page. They drive the site-wide Organization and WebSite nodes added to every page.

SettingFeeds
Site / organization nameOrganization.name, WebSite.name
LogoOrganization.logo (as an ImageObject)
sameAs (social profiles, one per line)Organization.sameAs[]
Search URLWebSite.potentialAction (SearchAction)
Organization descriptionOrganization.description
Default imageFallback image when a page has none (§7)
Config fallbackAnything not set in the CP can come from $config['site_jsonld'] in your front controller — useful for keeping values in version control. CP-saved values take precedence over config.

4.The render tag

{exp:site_jsonld:render} emits the full JSON-LD graph for the current page — the per-page node (Article, Review, …), plus breadcrumbs, plus the site-wide Organization/WebSite. Place it in your template's <head>.

ParameterWhat
typeSchema type for the page node (§5). Default Article.
titleHeadline / name of the page node.
imagePrimary image URL (width/height auto-parsed from a Cloudflare-resized URL).
default_imageFallback image when image is empty (§7).
author / author_url / author_sameasAuthor as a Person, with optional profile URL and sameAs.
crumbsauto builds a BreadcrumbList from the URL (§6); or pass your own.
itemsFor an ItemList: the list members.
rating / item_reviewedFor Review: the reviewRating and what's being reviewed.
TipOnly pass what a page has. The add-on omits empty fields rather than emitting blank values — which is exactly what keeps the markup valid.

5.Schema types

Switch the type parameter to emit a different page node. Each is correctly nested — an Article carries its author as a Person, a Review its reviewRating and itemReviewed, a VideoGame its platform and genre.

TypeUse for
Article / NewsArticle / BlogPostingEditorial content — articles, news, posts.
ReviewA review with a rating and the reviewed item.
VideoGameGame database / detail pages.
VideoObjectPages built around a video.
CollectionPageIndex / listing pages.
ItemListAn ordered list (e.g. a chapter or feature list).

Every page also gets the site-wide Organization and WebSite nodes and a BreadcrumbList — you don't add those per page.

7.Images & fallback

Image priority is own image first, fallback second: the add-on uses the page's image when present, and only falls back to default_image (or the Settings default) when the page has none — so a share card never overrides a real article image.

When the image URL is a Cloudflare-resized URL (/cdn-cgi/image/w=…,h=…/), the width and height are parsed from it automatically and emitted on the ImageObject, which is what validators want to see.

8.Validate a page

The Validate screen takes any URL on your site, fetches the rendered HTML, extracts every JSON-LD block, and checks each against schema.org / Google expectations — required fields, recommended fields, common mistakes. You get a per-block verdict: OK, warning, or error, with the specific field at fault.

Use it after wiring a new template, or to confirm a fix worked, without leaving the control panel or pasting into an external tool.

9.Site audit (crawl)

The Site audit screen samples real URLs across your channels, validates each the same way the single-page check does, and rolls the run up into checked / OK / warnings / errors. Each run is recorded, so you can watch structured-data health over time and catch a regression after a template change.

NoteThe crawl fetches your own pages over HTTP. On a site behind heavy edge caching, results reflect what's actually served to crawlers — which is the point.

10.Coverage & findings

The Coverage page explains, in plain language, which content types carry which schema and where the gaps are — so you know what's left to wire up rather than just a number. The Dashboard summarizes which types are live and how many pages each affects.

Across all of these, every warning and error carries a "Fix:" line — the concrete change to make (add an image, set the author, fill a breadcrumb name) — instead of a bare validator code. That's the difference between knowing something's wrong and knowing what to do about it.

11.Author archives

Site JSON-LD ships an extension that, on /articles/author/{slug} URLs, resolves the slug to a member and exposes two globals for that request:

GlobalWhat
{author_archive_id}The member id — use as author_id on a top-level channel:entries.
{author_archive_name}The screen name — for the heading, title, and schema.

This lets an author listing run a normal, paginated {exp:channel:entries author_id="{author_archive_id}"} instead of nesting inside {exp:query} (which strips limit/pagination) or an embed (whose params resolve too early).

12.Multi-Site Manager

Settings, audit runs, and coverage are per site. Switch the EE site picker first; the CP shows the current site's data. The render tag resolves the current site's settings automatically, so one template behaves correctly across all MSM sites.

13.Common questions

Do I need to add Organization / WebSite per page?

No — those come from your Settings and are added to every page automatically, along with the BreadcrumbList. You only specify the page-specific node via the render tag.

The breadcrumb validation complains about an empty name.

That's a page emitting a crumb with no label — usually a manually-built crumb list, or an old version. With crumbs="auto" the add-on skips empty segments. Re-validate after switching to auto or filling the missing name.

My share image is overriding the article image.

It shouldn't — priority is own image first, default_image only as a fallback. If you're seeing the fallback, the page's image parameter is resolving empty; check the field name and that the entry actually has an image.

Does the crawl hit my live site?

Yes — it fetches your own URLs over HTTP so it validates exactly what's served. It samples rather than crawling everything, to stay light.

Can I keep settings in config instead of the database?

Yes — $config['site_jsonld'] in your front controller is read as a fallback beneath the CP-saved values. Handy for version-controlled, per-environment values.

How do I uninstall?

Uninstall via Add-ons → Site JSON-LD → Uninstall — the settings and audit tables and the extension hook are removed cleanly.