Treat JSON-LD as a data model and a delivery format
JSON-LD expresses linked data using JSON. In an SEO implementation, the context identifies the vocabulary, the type names the kind of entity and properties describe its attributes or relationships. The document is data rather than executable application logic. Its usefulness depends on accurate modelling and dependable delivery, not the amount of code on the page.
Separate the entity from the page that describes it. A professional’s profile page and the professional are different objects. An article may reference the person as its author without becoming a profile itself. Start with a diagram or property list that states these roles, then serialise that model into JSON-LD.
Google recommends JSON-LD among its supported structured data formats, but a format preference is not a promise of enhanced search presentation. The structured data overview explains how vocabulary support differs from Google feature support. Choose the smallest accurate graph that serves the page’s purpose and can be maintained by the publishing system.
Use contexts, types and identifiers deliberately
Use the Schema.org context when describing Schema.org terms. Preserve exact vocabulary spelling: the schema type is Organization even when surrounding editorial prose uses British English. An invented spelling does not become a recognised type because it reads naturally. Review unfamiliar properties against their definitions rather than copying a plausible-looking example.
An @id identifies a node. A url property describes a URL associated with that node. They can share a base address but perform different jobs. A stable fragment identifier, such as an absolute profile URL followed by #person, can keep references consistent across pages. It does not require a separate route or imply a guaranteed external entity record.
Use @graph when grouping connected nodes improves clarity. It is not mandatory for every implementation. Several blocks can also coexist, provided their identities and claims are coherent. Document the convention before a second template or plugin starts emitting another version of the same person, publisher or page.
Generate JSON with an encoder and explicit field rules
Build a data structure from approved fields and pass it to a JSON encoder. Hand-built strings tend to fail around quotation marks, backslashes, line breaks and optional values. A title containing a double quote should remain valid data without a special editorial workaround. Keep serialisation concerns out of content fields.
Strict JSON does not allow comments or trailing commas. Strings need double quotes; numbers and booleans should retain the appropriate types. Omit an unknown optional property rather than filling it with an empty string, the word null or a placeholder. Decide those omission rules before rendering so they are consistent across templates.
Validate the encoded result with a strict parser, and make encoding failure visible to the build or publishing process. Never silently emit half a data block. Include test records containing apostrophes, non-ASCII names and multiline descriptions. These boundary cases expose the serialisation contract more effectively than repeatedly validating a simple demonstration name.
Account for the HTML embedding boundary
JSON syntax and safe HTML embedding are separate requirements. JSON-LD is normally delivered inside a script element with the application/ld+json type. The HTML parser still recognises a closing script sequence in that context, so an encoder must be used with an embedding policy that prevents content values from terminating the containing element.
For PHP output, select documented encoding flags appropriate to the surrounding HTML, check encoding errors and test the actual response bytes. Encoding angle brackets as Unicode escapes is one way to prevent a literal closing sequence from appearing inside a value. Avoid applying a generic HTML entity encoder to the whole JSON payload: that can change what a JSON parser receives.
Keep tutorial snippets escaped inside code elements. They should be readable examples, not additional live entity definitions emitted by the article. Review the response source after integration, since a CMS filter or templating layer can transform quotes and slashes after the generator has already produced valid JSON.
Trace every property to a source of truth
The evidence checklist for a JSON-LD block includes the template owner, source record, generated bytes, intended entity identifier, supporting visible content and validation result. Record the canonical page address and release reference. For external identity links, confirm that the destination represents the same entity rather than an adjacent topic or business directory category.
For shared entities, centralise approved public facts while allowing page-specific relationships to vary. An article’s headline belongs to the article record; the publisher’s name belongs to the publisher record. Combining both in one editable text field makes small editorial changes unexpectedly affect site-wide identity.
Keep confidential information out of the graph. Machine-readable output is public output, even when ordinary visitors do not see the block. Do not publish a private home address, internal identifier or unapproved contact number merely because a vocabulary property exists. Optionality should make omission straightforward when the fact is unnecessary or unsuitable for publication.
Illustrative worked example: one author referenced twice
This illustrative example uses a fictional professional, Alex Rowan, and a reserved example domain. It demonstrates identity references, not a complete Google feature implementation or any measured result. The profile and article records use the same approved author identity; no qualifications or client claims are implied.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Person",
"@id": "https://example.com/about/#person",
"name": "Alex Rowan",
"url": "https://example.com/about/"
},
{
"@type": "Article",
"@id": "https://example.com/guides/rendering/#article",
"headline": "Testing a rendered document",
"author": {"@id": "https://example.com/about/#person"}
}
]
}The reviewer checks that the live article visibly attributes authorship to Alex and that the profile destination is correct. Another guide should reference the same person identifier rather than create an unrelated author node. If the actual publisher is different, it needs its own accurately modelled relationship. The Person guide covers the evidence needed before expanding the identity record.
Diagnose parse, extraction and rendering failures separately
When a test detects no item, first establish whether the block reached the response. If absent, inspect template conditions and data availability. If present but unparsable, inspect the exact text after all output filters. If a strict parser accepts it, check the context, type and tool scope before concluding that the data is unsupported.
Competing hypotheses include broken JSON, an unrecognised vocabulary term, a Google tool that does not report that type and a client component that overwrites an earlier block. Compare source and rendered output to distinguish these explanations. Two tools disagreeing can be evidence of different coverage rather than a contradiction.
For client-generated blocks, test direct entry and transitions between distinct pages. A stale graph can retain the previous article’s headline even when the new page looks correct. The validation guide explains tool selection, while rendered HTML testing helps capture delivery differences. Do not fix an extraction failure by blindly duplicating the same block.
Define acceptance at the generation and deployment boundaries
Require valid JSON for every generated block, vocabulary terms with the intended meaning and no unsupported factual claims. Check identifiers against the documented convention. The chosen Google feature, if any, must meet its current requirements independently of general graph validity. Do not count unrelated detected items as evidence that the intended entity passed.
Exercise normal records, missing optional fields, quotation marks, non-Latin characters and strings resembling HTML closing tags. Confirm that the response remains well formed and that documentation examples remain inert. For dynamic delivery, repeat after navigation to a second record and ensure the old values do not survive.
Compare deployed output with the approved generation fixture. A build-time pass cannot detect a production cache serving an older document or a downstream component adding another graph. Assign ownership for any duplicate definitions. Acceptance should produce an inspectable record of expected and observed entities, rather than a single pass label detached from the page and release.
Rollback the faulty boundary and preserve valid relationships
If an encoder change breaks many pages, restore the known accurate serialiser or disable its emission until repaired. If one record contains a wrong external identity, correct that record instead. Avoid replacing the entire graph to resolve a narrow field problem. A broad rollback can remove valid page relationships that were not involved in the incident.
Verify the public document after rollback and account for cache invalidation. A previous template may expect different source fields, so restoring code without restoring compatible data can create a second failure. Keep a record of affected identifiers, especially during migrations, when references can drift between old and new addresses.
Use structured data release QA to retain fixtures and recovery criteria. JSON-LD is an explicit description, not an instruction that forces indexing, rankings or AI citations. Google’s FAQ rich results were retired in May 2026; changing the serialisation format cannot restore a retired feature or create support for an otherwise unsupported search treatment.
Frequently asked questions
Does JSON-LD need to be in the page head?
Google can process JSON-LD in the head or body. Choose a predictable template location and test the emitted document. Placement does not compensate for invalid JSON, inaccurate claims or a block that the production delivery path removes before a consumer can access it.
Can several JSON-LD blocks appear on one page?
Yes. Review the entities and relationships across all blocks rather than counting elements alone. Separate blocks can describe different things accurately. Conflicting definitions of the same identifier need investigation, especially when a plugin and a template both own publisher or author information.
Are comments allowed inside JSON-LD?
JSON-LD uses JSON syntax, so JavaScript-style comments and trailing commas do not belong in the payload. Explain the example outside its code block. Parse the final generated bytes strictly, because an editor or output filter can introduce a syntax error after the original record was approved.
Does @id have to be an indexable standalone page?
An identifier can use a fragment on an existing absolute URL to identify an entity. That does not create a new document. Prefer stable, coherent identifiers and separately provide an appropriate public URL where useful. Do not treat the identifier as proof of external recognition.
Should all possible properties be included?
No. Include properties that accurately describe the entity and can be maintained. Missing optional information is preferable to a guessed value. Required properties for a deliberately targeted Google feature need separate checking against its current guide; vocabulary completeness is not an SEO objective in itself.