JSON-LD
Structured data is what tells search engines and AI agents what a page is — not just its words. pageflare emits schema.org JSON-LD on every page by reading the content model, so you get strong structured data without hand-writing <script type="application/ld+json"> blocks.
A typical page ends up with three to four JSON-LD blocks:
Organization— site-wide brand identity (whensite.yaml -> brand.organizationis set).- Page type —
Article/BlogPosting/WebPage/Product/ProfilePage— derived from frontmatter + content type. BreadcrumbList— built from the URL path.- Custom overrides — anything you add under
seo.jsonld(FAQPage, HowTo, etc.).
Each block is emitted as a separate <script type="application/ld+json" data-pf="..."> tag, in deterministic order. Re-running pageflare produces byte-identical output.
Organization block PRO
Section titled “Organization block ”When content/site.yaml declares brand.organization, pageflare emits this block on every page:
brand: organization: name: "Acme Inc." url: "https://acme.dev" logo: "/content/assets/logos/acme-mark.svg" same_as: - "https://github.com/acme" - "https://x.com/acme"Becomes:
<script type="application/ld+json" data-pf="jsonld.organization">{ "@context": "https://schema.org", "@type": "Organization", "name": "Acme Inc.", "url": "https://acme.dev", "logo": "https://acme.dev/content/assets/logos/acme-mark.svg", "sameAs": [ "https://github.com/acme", "https://x.com/acme" ]}</script>same_as is what links your entity to its public profiles (GitHub, X, LinkedIn, Crunchbase, Wikipedia/Wikidata). It’s the single highest-leverage field for AI Knowledge Graph linkage.
Page-type block
Section titled “Page-type block”The page-type block is built from the page’s frontmatter and inferred type. pageflare picks the type using this precedence:
-
Explicit
seo.og.type— wins absolutely:seo.og.typeschema.org @typearticleArticle(orBlogPostingforposts/)websiteWebPageproductProductprofileProfilePage -
Content type
posts/— defaults toBlogPosting. -
Everything else — defaults to
WebPage.
Article / BlogPosting
Section titled “Article / BlogPosting”For a content/posts/hello-world.md like:
---title: "Hello, world"description: "First post on the new blog."publish: date: 2026-05-01 updated: 2026-05-12 author: "Shiva Kumar"seo: og: image: "/content/assets/og-hello.png"---pageflare emits:
{ "@context": "https://schema.org", "@type": "BlogPosting", "headline": "Hello, world", "description": "First post on the new blog.", "url": "https://acme.dev/blog/hello-world/", "datePublished": "2026-05-01", "dateModified": "2026-05-12", "author": { "@type": "Person", "name": "Shiva Kumar" }, "image": "https://acme.dev/content/assets/og-hello.png", "articleBody": "First post on the new blog. ..."}articleBody is the markdown body converted to plain text and capped at 5,000 characters. This gives crawlers a token-efficient summary of the page content.
WebPage
Section titled “WebPage”For non-post pages, the same fields appear but the type is WebPage and there’s no articleBody:
{ "@context": "https://schema.org", "@type": "WebPage", "name": "About", "description": "About the team.", "url": "https://acme.dev/about/"}Product and ProfilePage
Section titled “Product and ProfilePage”Product and ProfilePage follow the same skeleton. They’re triggered by seo.og.type: product or seo.og.type: profile respectively, and exist to let you mark up landing pages and team-member pages without manual JSON.
BreadcrumbList
Section titled “BreadcrumbList”Built from the page URL, regardless of content type:
<!-- /docs/getting-started/installation/ → --><script type="application/ld+json" data-pf="jsonld.breadcrumb">{ "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://acme.dev/" }, { "@type": "ListItem", "position": 2, "name": "Docs", "item": "https://acme.dev/docs/" }, { "@type": "ListItem", "position": 3, "name": "Getting Started", "item": "https://acme.dev/docs/getting-started/" }, { "@type": "ListItem", "position": 4, "name": "Installation", "item": "https://acme.dev/docs/getting-started/installation/" } ]}</script>Segment names are humanized — getting-started → Getting Started. The root is always labeled Home and linked to site.url.
The home page itself (/) gets no BreadcrumbList — a single-item breadcrumb is meaningless.
Custom overrides
Section titled “Custom overrides”For schema.org types pageflare doesn’t auto-build — FAQPage, HowTo, Recipe, Event, Course, SoftwareApplication, etc. — declare them under seo.jsonld in frontmatter:
---title: "Pricing FAQ"seo: jsonld: - "@type": FAQPage mainEntity: - "@type": Question name: "Is there a free tier?" acceptedAnswer: "@type": Answer text: "Yes — the Free tier covers up to 10 pages per project." - "@type": Question name: "Can I cancel anytime?" acceptedAnswer: "@type": Answer text: "Yes, billing is monthly with no minimum commitment."---Each entry under seo.jsonld is emitted as a separate <script> block with marker data-pf="jsonld.custom.<index>". @context: "https://schema.org" is added automatically when absent.
You can stack multiple custom types on one page — e.g. a recipe page might have Recipe + HowTo + BreadcrumbList.
Frontmatter validation
Section titled “Frontmatter validation”pageflare seo fix validates seo.jsonld entries on load and warns when an entry is missing @type or isn’t a mapping. This catches the most common authoring mistake before it ships to production.
Block ordering
Section titled “Block ordering”JSON-LD blocks are emitted in this fixed order, before </head>:
Organization(ifbrand.organizationset)- Page-type block (
Article/BlogPosting/WebPage/Product/ProfilePage) BreadcrumbList(except on the home page)- Custom overrides, in array order
The order is stable across runs — diffing optimized output won’t show spurious churn.
Round-tripping with bootstrap
Section titled “Round-tripping with bootstrap”pageflare seo fix --bootstrap-content scans optimized HTML for existing JSON-LD blocks and converts them into seo.jsonld entries in frontmatter. Blocks already marked data-pf="..." are skipped (they’d be regenerated anyway), so the bootstrap captures only hand-authored or upstream-injected JSON-LD.
Inspecting JSON-LD
Section titled “Inspecting JSON-LD”Validate the emitted blocks with Google’s Rich Results Test or Schema Markup Validator. Both accept a URL or a pasted HTML snippet.
Related
Section titled “Related”- Content Model — directory layout,
site.yaml, brand defaults. - Frontmatter Reference — the
seo:block in full. - Markdown for Agents —
llms.txtand edge markdown.