Build and audit structured data on Webflow sites.
Webflow's page-level JSON-LD field (Page Settings, also writable through the Data API) is the right home for schema on a Webflow site. It lands in the served HTML, which matters because most AI crawlers do not run JavaScript. The field has two platform limits that were found by testing against live sites, and nearly every decision in this skill follows from them. Read references/platform-limits.md before you write anything.
Hard rules
These keep schema work safe on a live site. Hold them on every task.
- Leave publishing to a person. Stage changes unpublished and say clearly that they are waiting for a publish. Only publish when the site owner tells you to in the conversation.
- Do not edit body content. Schema work should never touch a post's main rich text field. Ask first if a task seems to need it.
- Never invent a fact, date, author, rating or claim to fill a schema property. Bind it to a real field or leave the property out. Made-up structured data risks a manual action and is worse than none.
- Never trust a binding until you have seen it resolve on the live page. After a publish, fetch the URL and read the rendered JSON-LD.
Quick start workflow
- Orient. Get the Webflow
site_id, confirm the canonical host (the custom domain actually attached, and whetherwwwredirects), list pages and find the Collection templates. Read the schema already on the template and on one live page. - Pick the architecture. Is the content you want in schema rendered on the page, or does it exist only to feed schema? See the table below.
- Check the content. Bound CMS values must be PlainText (or Number, Date, ImageRef, Link) and free of straight apostrophes, straight double quotes and ampersands. Run scripts/check_bindable_text.py over the field values.
- Write one
@graph. One script block, one@context, every node inside@graph, every URL absolute on the canonical host. - Write it through the API with the binding token written without the backslash. See references/writing-via-api.md.
- Hand off for publishing, then audit the live page with scripts/audit_jsonld.py across several items, not just one.
Choosing the architecture
| Situation | Architecture | Server-rendered | Rich text | Notes |
|---|---|---|---|---|
| Content exists only to feed schema (FAQ or takeaway fields that never display) | A. Bind CMS fields in the JSON-LD field | Yes | No | The default. Use whenever you can. |
| Content is rendered on the page (FAQ accordions, visible takeaways) | B. Client-side script reads the DOM | No | Yes | Google renders it. Most AI crawlers will not see it. |
| A Cloudflare Worker already fronts the site | C. Edge injection with HTMLRewriter | Yes | Yes | Best of both, only where a Worker already exists. |
Full detail, including the attribute contracts for the scripts, is in references/architectures.md.
The two limits, in brief
- Webflow HTML-escapes every CMS value bound into the JSON-LD field. A straight apostrophe renders as
', a double quote as", an ampersand as&, and crawlers read those codes as literal text. Typographic punctuation is the fix: a smart apostrophe (’) passes through unescaped. Spell&as "and". - RichText fields bound into the JSON-LD field come back as an empty string. Not stripped, empty. Rich text can never be template-bound.
Literal text typed into a static page's JSON-LD field is not escaped. The limits apply to {{wf ...}} bindings.
Reference documentation
Platform
- Platform limits: the escaping and RichText limits, which field types bind, and what is safe to write
- Choosing an architecture: bind, client-side script or edge injection, with the ready-made scripts
Building
- Writing schema via the API: read and write calls, the binding token gotcha, token rules and variable item counts
- Worked examples: a blog post
@graph, a case study and a blog or work index page - What auto-generate gets wrong: the problems in Webflow's generated schema and how to fix each one
Checking
- Auditing live schema: what to report, how to read Search Console verdicts, and how to finish a piece of work
- New site checklist: what to capture before any schema work on a site you have not worked on
Searching references
# List all references with metadata
python scripts/search_references.py --list
# Search by tag (exact match)
python scripts/search_references.py --tag binding
# Search by keyword (across name, description, tags, and content)
python scripts/search_references.py --search "search console"
Scripts
scripts/audit_jsonld.py: fetch one or more live URLs and report parse failures, unresolved tokens, HTML entities, empty values, relative URLs, non-ISO dates, self-serving reviews and duplicate typesscripts/check_bindable_text.py: check text (a CSV export, a file or stdin) for characters that will break once bound into the JSON-LD fieldscripts/search_references.py: search the reference files by tag or keyword
Assets
assets/faq-schema.html: FAQPage builder for Architecture B, driven bydata-faq-item,data-faq-questionanddata-faq-answerattributesassets/takeaways-schema.html: ItemList builder for Architecture B, driven bydata-takeawayon each item
License
MIT