Skip to content
MCG Filament CMS Demo

Structured data

Every page on the site publishes a machine-readable summary of itself alongside the visible page. It changes nothing on screen, and visitors never see it. Search engines read it to determine what a page is, who published it, and whether the site represents a real organization at a real address. Google's documentation calls this *structured data*, and the format it is written in is JSON-LD.

The CMS assembles the structured data automatically when a page is rendered, from values already entered in the panel. This section lists which values, so the effect of changing one is known.

Viewing the structured data

  1. Open any page of the public site in a browser.
  2. Right-click the page and choose View Page Source.
  3. Search the source for ld+json.

Each page has exactly one such block, near the top, inside <head>.

What the block contains

The block contains three entries, always in this order. The wrapper holding them is called a *graph*. The entries sit in one block rather than three for the reason given in The @id cross-references.

  1. The publisher: who runs the site, with its name, logo, tagline, telephone, email, postal address and social profiles. This entry is identical on every page. A search engine reads one page at a time and cannot follow a reference to markup that exists only on the home page, so the publisher is repeated on each page.
  2. The site: its web address and its name.
  3. The page: its title, description, web address, the date it was first published, the date it was last changed, its sharing image, its author where the content type records one, and what kind of page it is.

Where each value comes from

Each row names the field that controls a value.

The publisher entry:

Value in the markup Controlled by
Kind of organization Site settings β†’ Organization β†’ Kind of organization
Name Site settings β†’ Organization β†’ Legal name, or Site name when Legal name is blank
Logo Site settings β†’ Identity β†’ Logo
Description Site settings β†’ Identity β†’ Tagline
Telephone Site settings β†’ Organization β†’ Telephone
Email Site settings β†’ Organization β†’ Email
Postal address Site settings β†’ Organization β†’ Street address, City or town, State, county or region, Postal code, Country
Social profiles Site settings β†’ Social links
Web address The site's own address. Not a field.

The page entry:

Value in the markup Controlled by
Kind of page The content type, overridable per page at Page settings β†’ SEO β†’ Page type
Name The page's Title
Description Page settings β†’ SEO β†’ Meta description, falling back to the excerpt or summary field where the content type has one
Web address The page's slug and its position in the tree
Sharing image The social sharing image, card image or hero image, whichever the content type records
Author The Author field, where the content type has one
Date published When the page was first published. Recorded automatically; not a field.
Date modified When the page was last saved. Recorded automatically; not a field.

Filling in the publisher

Filling in the publisher is done once per site. It does not need revisiting when a page is added.

  1. In the sidebar, select Site settings.
  2. Select the Organization heading to expand that section, which is collapsed by default.
  3. Set Kind of organization. The choices are Organization, **Local business (has a place customers visit), Corporation, Non-profit**, Educational organization and Government organization. Choose the local business option only if customers visit an address in person: it allows the address to appear as a map result, so choosing it for a business with no visitable location produces a map pin nobody can use.
  4. Fill in Telephone, in international form (for example +1-856-673-2102), and Email.
  5. Fill in the five address fields. For Country, a two-letter code such as US or GB is preferred. If all five are left blank, the address is left out of the markup instead of being published empty, which is correct for a business with no public address.
  6. Leave Legal name blank unless the registered company name differs from the site name.
  7. Select Save.

The @id cross-references

The markup contains two values that look incomplete:

JSON

"publisher": { "@id": "https://example.com#organization" }
"isPartOf":  { "@id": "https://example.com#website" }

Both are pointers, not missing values. The publisher entry labels itself "@id": "https://example.com#organization", and the other two entries point at that label instead of repeating the name, logo, telephone and address. A search engine resolves each pointer within the same page. A pointer can only be resolved against an entry in the same graph, which is why the three entries share one block.

Overriding the kind of page

  1. On the page's edit screen, expand Page settings, then expand SEO.
  2. Set Page type.

The default, Decided by the content type, is correct in nearly every case: an ordinary page is a web page and a blog post is an article, and the content type already states that.

Change it in the cases the content type cannot detect:

Page Choose
The site's About page About page
The site's Contact page Contact page
A page whose purpose is to list other pages Collection or index page
A page that consists of questions and answers FAQ page

The list also offers Web page, Profile page and Checkout page.

Setting a type that does not describe the page does not improve its ranking. A search engine that finds markup contradicting the page can disregard the site's markup on every page, so an inaccurate choice causes more harm than the default.

Custom JSON-LD

Custom JSON-LD is a field in the SEO section, below Page type. It is the only part of this feature that requires knowledge of the schema.org vocabulary, and most sites never use it. The generated markup is complete without it, so leave it empty if the vocabulary is unfamiliar.

The field merges hand-written JSON-LD over the page entry, one property at a time, so nothing needs to be restated:

  • Entering {"award": "Best in show"} adds an award property and leaves every generated value unchanged.
  • Entering {"description": "My own wording"} replaces the generated description and leaves every other value unchanged.

The field is validated when the page is saved, so invalid JSON is reported as a form error and never reaches the public page.

What is not editable in the panel

Two things are set in code, not in a field, and changing either needs a developer:

  1. The schema.org type of each kind of content. A blog post is a BlogPosting, a job opening is a JobPosting, and a product is a Product. The type is defined on the content type because it holds for every page of that type. If it were a panel field, an editor would have to choose it correctly on every new post. The Page type field still overrides it for a single page.
  2. The extra properties a type requires. Each schema.org type has required properties, and most of them correspond to no CMS field: a JobPosting needs a hiring organization and a job location, and a Product needs an offer. A developer supplies these once on the content type. See content-types.md.

If a single page needs a property not covered above, add it in Custom JSON-LD; no developer is needed.

Disabling structured data

A site that publishes its own structured data by another means should switch this feature off rather than publish both. Two descriptions of one address give a crawler conflicting answers, and the site cannot control which one the crawler uses. The setting is structured_data.enabled in config/cms.php, and changing it is a developer change.