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
- Open any page of the public site in a browser.
- Right-click the page and choose View Page Source.
- 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.
- 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.
- The site: its web address and its name.
- 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 |
| 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.
- In the sidebar, select Site settings.
- Select the Organization heading to expand that section, which is collapsed by default.
- 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.
- Fill in Telephone, in international form (for example
+1-856-673-2102), and Email. - Fill in the five address fields. For Country, a two-letter code such as
USorGBis 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. - Leave Legal name blank unless the registered company name differs from the site name.
- Select Save.
The @id cross-references
The markup contains two values that look incomplete:
"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
- On the page's edit screen, expand Page settings, then expand SEO.
- 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 anawardproperty 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:
- The schema.org type of each kind of content. A blog post is a
BlogPosting, a job opening is aJobPosting, and a product is aProduct. 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. - The extra properties a type requires. Each schema.org type has required properties, and most of them correspond to no CMS field: a
JobPostingneeds a hiring organization and a job location, and aProductneeds an offer. A developer supplies these once on the content type. Seecontent-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.