JSON-LD is the format most sites use to write structured data: a small block of text in the page's head that browsers ignore and search engines read. The letters stand for JavaScript Object Notation for Linked Data, which is less frightening than it sounds. It is a list of facts in curly brackets, using a vocabulary (schema.org) that Google, Bing and the AI assistants all understand.
You do not need to be a developer to read it, and you do not need to write it from scratch. Below is a complete example for a personal site, annotated, that you can adapt. Person schema: what to put on your own site explains the choices behind each property.
Where it goes
Inside the head of your home page, between script tags with the type application/ld+json. One block per page. A page can describe several things in one block by using an @graph array, which is what the example does.
The example, annotated
The person is invented. Replace every value with your own; keep the structure.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Person",
"@id": "https://mariachen.com/#person",
"name": "Maria Chen",
"alternateName": "Maria L. Chen",
"description": "Founder and CEO of Northwind Analytics and author of Counting What Matters. Pricing strategy for subscription businesses. Based in Ann Arbor, Michigan.",
"url": "https://mariachen.com/",
"image": { "@id": "https://mariachen.com/#headshot" },
"jobTitle": "Founder and CEO",
"worksFor": { "@id": "https://northwindanalytics.com/#organization" },
"alumniOf": { "@id": "https://mariachen.com/#umich" },
"birthPlace": { "@type": "Place", "name": "Ann Arbor, Michigan" },
"knowsAbout": ["Pricing strategy", "Subscription businesses", "SaaS metrics"],
"sameAs": [
"https://www.linkedin.com/in/mariachen/",
"https://x.com/mariachen",
"https://www.youtube.com/@mariachen",
"https://www.crunchbase.com/person/maria-chen"
]
},
{
"@type": "ImageObject",
"@id": "https://mariachen.com/#headshot",
"url": "https://mariachen.com/images/maria-chen.jpg",
"width": 800,
"height": 800
},
{
"@type": "Organization",
"@id": "https://northwindanalytics.com/#organization",
"name": "Northwind Analytics",
"url": "https://northwindanalytics.com/",
"founder": { "@id": "https://mariachen.com/#person" }
},
{
"@type": "CollegeOrUniversity",
"@id": "https://mariachen.com/#umich",
"name": "University of Michigan",
"sameAs": "https://en.wikipedia.org/wiki/University_of_Michigan"
},
{
"@type": "Book",
"@id": "https://mariachen.com/#counting-what-matters",
"name": "Counting What Matters",
"author": { "@id": "https://mariachen.com/#person" },
"datePublished": "2024"
},
{
"@type": "WebSite",
"@id": "https://mariachen.com/#website",
"url": "https://mariachen.com/",
"name": "Maria Chen"
},
{
"@type": "WebPage",
"@id": "https://mariachen.com/#webpage",
"url": "https://mariachen.com/",
"isPartOf": { "@id": "https://mariachen.com/#website" },
"mainEntity": { "@id": "https://mariachen.com/#person" },
"dateModified": "2026-10-18"
}
]
}
</script>
Line by line, the parts that matter:
- @context tells the reader which vocabulary this is. Always schema.org.
- @graph lets one block describe several connected things. Each item is a node.
- @id is the node's permanent address. Notice the Person's @id is used again by the Organization's founder, the Book's author and the WebPage's mainEntity. That reuse is the whole point: one node, referenced, never repeated.
- worksFor points at an Organization node on the company's own domain, because Maria owns it and it has a site. If she worked somewhere she did not own, the Organization node would live on her domain, as the university does.
- sameAs is her profiles, not her company, not her book, not a podcast she was on.
- birthPlace is here only because her home page says it in a sentence. Schema states what the page states.
- The WebPage node says what this page is (the page about Maria) without being a second description of Maria.
Adapting the example to a site builder
If your site is on WordPress, Squarespace, Webflow or Wix, you are not editing HTML files directly, but every one of them lets you put a block of code in the page's head.
WordPress: the simplest route is a plugin that lets you paste raw JSON-LD into the head of a specific page, or the code injection field in your theme. Avoid the big SEO plugins' automatic schema for a personal site; they add their own Person and Organization nodes with their own identifiers and you end up with duplicates. If you keep one of them, turn its schema output off for the home page and use yours.
Squarespace: Settings, Advanced, Code Injection for site wide, or the page's own Advanced tab for one page. Use the page level option for the home page so the Person block is on one page only.
Webflow: page settings, custom code, inside head tag. Webflow also has a visual schema field on CMS items; do not use both.
Wix: the SEO panel on each page has a structured data section where you paste the block. Wix adds its own WebSite block; leave it, it does not conflict.
In every case, after publishing, view the live page's source and search for ld+json to confirm it is there once, not twice.
Reading someone else's
A good way to learn the shape is to look at a page that has it right. View the source of a well built personal site, search for ld+json, copy the block into the validator and read it as a list of statements. Who is the Person. What is the @id. What points at it. Which profiles are in sameAs. Where the Organization nodes live. You will quickly see the difference between a block somebody designed and a block a template generated: the designed one reuses one identifier everywhere, and the generated one repeats the name in three places with no identifier at all.
Keeping it current
The block is not finished when it validates. Roles change, books get published, profiles get added. Each time the prose on the home page changes, the block should change to match, and dateModified should move. Once a quarter, run the Rich Results Test again and walk the sameAs list by hand, because a profile you deleted is now a dead link in your record. If appearances are listed on the media kit, each new one is a new node pointing at your @id, which is the cheapest way the graph grows.
What a media kit page would carry
Not another Person. A WebPage with mainEntity pointing at https://mariachen.com/#person, plus an ImageObject for the downloadable headshot. The identifier does the linking; the bio stays where it is.
Mistakes the validator will not catch
The validator checks syntax and vocabulary. It does not know whether you told the truth or whether you described yourself twice. The errors it passes silently are the ones that matter most for a person:
- A sameAs address that points to a different person's profile with your name. Valid, and wrong.
- An @id on your Person that differs from the @id your media kit's mainEntity points at, by a trailing slash or a capital letter. Two identifiers, one person, nothing connected.
- A worksFor Organization whose @id lives on a domain you do not control and have not coordinated with, so the company's own schema contradicts yours.
- A fact in the block, such as a birthplace, that the visible page never states. Parses fine; the machine has nothing to corroborate it against.
- Copying the example's values. Maria Chen does not exist. A surprising number of live sites carry a template author's name in their schema.
Walk the block by hand once with these in mind. It is a five minute read and the validator cannot do it for you.
How to check Google read it
- Validate the syntax. Paste the block into the Schema Markup Validator at validator.schema.org. A missing comma breaks the whole block silently, and this catches it.
- See what Google sees. Put your page address into Google's Rich Results Test. It shows the items it parsed and any errors. Person is not a rich result type, so "no rich results" is fine; what you want is zero errors.
- Watch it in Search Console. Once your domain is verified, the Enhancements and Pages reports show whether the page is indexed and whether structured data errors appear over time. Search Console is where the record proves itself.
- Walk your own graph. List every @id in the block. Confirm every reference points at a node that exists. Confirm there is exactly one Person across the whole site.