Automatic Metadata, Open Graph, and JSON-LD — Eleventy Style
Most Eleventy setups start the same way: every project re-implements SEO from scratch.
Another base.njk, another batch of <meta> tags, another copy-pasted JSON-LD snippet from schema.org.
It’s boring, error-prone, and inconsistent across projects.
Quesby solves this the only sane way: one SEO model, one source of truth, generated at build time.
No plugins.
No runtime.
No React components disguised as SEO helpers.
This is how it works.
The Idea in 10 Seconds
Quesby takes:
site.json + frontmatter → SEO model → complete <head> + JSON-LD
Everything happens during the Eleventy build.
Templates stay clean.
SEO stays consistent.
In base.njk, it looks like this:
{%- set seoModel = page | seoModel(site, pageData) -%}
{{ seoModel | seoHeadHtml(site) | safe }}
{{ seoModel | seoJsonLd(site) | safe }}
That’s the entire integration surface.
Site-Level Defaults (One File)
Global SEO config lives in:
src/_data/site.json
Example:
{
"name": "Quesby",
"url": "https://quesby.dev",
"description": "A modern Eleventy boilerplate",
"socialImage": "/assets/images/og-default.jpg",
"twitter": "@quesby",
"language": "en-US"
}
Quesby uses this for:
- default description
- default Open Graph image
- canonical URL generation
- Twitter Card data
- JSON-LD publisher info
You define it once.
Every page inherits it automatically.
Frontmatter: Minimal When You Want, Detailed When You Need
Simple page:
---
title: "My Page"
description: "Short summary."
---
Full blog post:
---
title: "How to Build Better Websites"
seoTitle: "Complete Guide to Modern Web Development"
description: "Learn the principles behind fast, accessible websites."
image: "/assets/images/cover.jpg"
postType: "article"
author: "John Doe"
date: "2024-01-15"
---
Quesby applies fallback rules:
- Title:
`seoTitle` → `title` → `site.name` - Description:
`description` → `site.description` - Image:
`image` → `site.socialImage`
You don’t repeat yourself.
Pages don’t need boilerplate.
Automatic Head Metadata
From the SEO model, Quesby generates:
Basic SEO
<title><meta name="description"><link rel="canonical">-
<meta name="robots">(withnoindexsupport)
Open Graph
og:typeog:titleog:descriptionog:urlog:image
Twitter Cards
-
`twitter:card`(`summary_large_image`) `twitter:site``twitter:title``twitter:description``twitter:image`
No manual tags.
No plugin configuration.
No React component SEO helper nonsense.
JSON-LD Structured Data
Quesby also outputs JSON-LD for:
Blog posts (BlogPosting)
- headline
- description
- image
- author
- publisher
- datePublished
- dateModified
Site (WebSite)
- name
- url
- description
- publisher
Rendered via:
{{ seoModel | seoJsonLd(site) | safe }}
Again: static, not runtime.
Sitemap, Robots, and Noindex Integration
Quesby integrates SEO beyond the <head>:
- Sitemap generated from the
`sitemap`collection - Pages with
`noindex`or`eleventyExcludeFromCollections`are auto-excluded -
`robots.txt`generated automatically and linked to the sitemap
Everything stays consistent with the same SEO model.
Opt-Out When Needed
For special pages:
---
seoDisableCoreHead: true
seoDisableCoreJsonLd: true
---
You can disable core SEO on a per-page basis and write your own tags.
No lock-in.
Why This Matters for Eleventy Developers
If you build Eleventy sites regularly, you already know the pain:
- copy-pasting head tags
- rewriting JSON-LD
- fixing Open Graph mismatches
- forgetting canonical URLs
- duplicating logic across pages
Quesby removes all of that.
- One config file
- One model
- One consistent output
- Zero runtime JavaScript
- Zero framework dependencies
HTML-first, static-first, and boring in all the right ways.
Final Thoughts
If you like Eleventy but don’t want to rebuild SEO infrastructure for every project, Quesby gives you:
- strong defaults
- static, predictable output
- extensibility when needed
- zero client-side bloat
It’s a lightweight alternative to plugin-heavy or framework-heavy approaches, built specifically for people who prefer clean HTML and simple pipelines.
More info:
https://quesby.dev
Top comments (0)