Forma

FAQ and custom schema without a plugin

Forma generates FAQPage JSON-LD straight from the visible accordion markup, and a data-fx-schema escape hatch handles everything else — validated on save, merged into one script tag.

Every FAQ schema tutorial tells you to write the JSON-LD once, then write the visible accordion again in HTML, then remember to update both when the answer changes. Two copies of the same fact drift apart within a month. Forma's FAQ support has exactly one copy.

Write the accordion, not the schema

Toolbar → Snippets → FAQ block drops a starter into the editor:

[[faq-ui]]
<div class="fx-faq" data-fx-faq>
  <details class="fx-faq-item" open>
    <summary>Do you offer refunds?</summary>
    <div class="fx-faq-a"><p>Yes, within 30 days of purchase.</p></div>
  </details>
  <details class="fx-faq-item">
    <summary>How fast is setup?</summary>
    <div class="fx-faq-a"><p>Most sites go live within 48 hours.</p></div>
  </details>
</div>

[[faq-ui]] is a stock snippet that styles the accordion — native <details>/<summary>, no JavaScript. Save the page. That is the entire job.

On render, Forma scans the saved HTML for data-fx-faq blocks, pulls the question out of each <summary> and the answer out of each .fx-faq-a, and builds a FAQPage node:

{
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Do you offer refunds?",
      "acceptedAnswer": { "@type": "Answer", "text": "Yes, within 30 days of purchase." }
    }
  ]
}

Edit the answer in the visible accordion next month and the schema updates itself, because it was never a separate fact to begin with. This also happens to be what Google actually wants: the rich-results guidelines require the marked-up text to match what a visitor sees, and a hand-maintained JSON-LD blob is the most common way sites fail that check without realizing it.

When the UI doesn't have a button for it

FAQ covers one shape. Real sites eventually need Event, Recipe, Course, or some other schema.org type Forma has no settings pane for. For that, drop a script tag straight into the page or post content:

<script type="application/ld+json" data-fx-schema>
{"@type":"Event","name":"Launch Party","startDate":"2026-09-10T18:00:00-05:00"}
</script>

The data-fx-schema attribute is what makes this safe to write. Forma strips any bare application/ld+json tag on render — it owns that slot in <head> and won't let a stray script tag fight it for control of the page's structured data. Flag the tag with data-fx-schema and Forma validates it on save instead: bad JSON or a missing @type comes back as a warning in the save toast and the block is dropped, not published half-broken. A valid block gets merged into the same @graph as everything else — WebSite, Organization, FAQPage, BreadcrumbList — as one script tag, not five competing ones.

You can pass a single object, an array of objects, or {"@graph": [...]} if you're describing more than one thing on the same page.

The rule that makes both of these work

Structured data that isn't derived from something a human can read is a liability, not an asset — it's the one part of the page nobody proofreads because nobody sees it. FAQ schema comes from the accordion your visitors actually click. Custom schema still lives in the content, in a tag you wrote and can see, not tucked into a settings field three menus deep. One thing to maintain, one thing to get wrong.