| description | Build a complete FAQ accordion component from scratch in four hands-on parts |
|---|---|
| icon | list-check |
In this tutorial you'll build a production-quality FAQ accordion—com.example.faq—from an empty folder to a themed, interactive component that emits structured data for search engines. Each part ends with complete, working files, so you can stop after any part and still have a component that runs.
{% hint style="success" %} Every pattern here comes from the open-source Core Pack. The relevant core component is named and linked at each step—keep its source open alongside the tutorial and compare as you go. {% endhint %}
An FAQ component whose questions are managed in the inspector, styled by the theme, and rendered as an accessible accordion:
- Collection-driven content — users add, edit, and reorder questions in a dedicated inspector panel
- Theme-aware styling — accent color, item gap, corner radius, and question text style all resolve through Theme Studio controls
- Flexible answers — each answer is plain text by default, or a full dropzone that accepts any other component
- Accordion behavior — one-open-at-a-time (or allow multiple), optional first-item-open-on-load, and smooth collapse transitions via Alpine.js
- Editor-friendly — every answer stays open on the edit canvas, and placeholder questions appear while the collection is empty
- SEO-ready — emits
FAQPageJSON-LD structured data into the page head
By the end of Part 4 the component folder looks like this:
com.example.faq/
├── info.json
├── properties.json
├── collections/
│ └── questions/
│ ├── info.json
│ ├── properties.json
│ └── defaults.json
├── hooks.js
└── templates/
├── index.html
└── alpine.html
You should have Elements installed with a Dev Pack you can edit, and know how to add a component to a page and preview it. The Quickstart covers all of that, including short videos on creating a pack and editing its files:
{% content-ref url="../../getting-started/getting-started.md" %} getting-started.md {% endcontent-ref %}
A passing familiarity with Tailwind CSS helps but isn't required—Component Styling explains the utility-class approach the tutorial follows, and there is no build step to set up.
The parts build on each other in order. Each one starts from the exact files the previous part ended with:
- Part 1: Scaffolding & Properties — create the component folder, describe it in
info.json, define every inspector control inproperties.json, compose theme-driven classes in a minimalhooks.js, and render a static two-question accordion. - Part 2: Collections & Dynamic Dropzones — replace the hard-coded questions with a
questionscollection, precompute per-item IDs and ARIA attributes in hooks, and let individual answers switch between plain text and a dropzone. - Part 3: Interactivity with Alpine.js — register an Alpine.js factory through
@portal(bodyEnd), wire up open/close state with one-open-at-a-time behavior, pass configuration through a data attribute, and addx-collapsetransitions. - Part 4: Edit Mode, Theming & Polish — keep all answers open on the canvas with
@if(edit), show placeholder items while the collection is empty, and emitFAQPageJSON-LD via@portal(headEnd).
If you only need one technique—say, collection-driven dropzones—you can read that part on its own. The "files so far" listings at the end of each part let you catch up without retyping every step.
A few things to know before you start:
- Code listings are complete. Multi-file examples name the file in a comment on the first line (
// hooks.js,<!-- templates/index.html -->) or in the heading above the block—type them in exactly as shown. - Checkpoints end every part. Compare your files against the checkpoint before moving on; each part assumes the previous checkpoint verbatim.
- Core Pack references are real. When a step says a pattern comes from Tabs, Table, or Accordion, that component's source in the open-source Core Pack contains the original—reading it alongside the tutorial is the fastest way to level up.
- No build tools required. Everything is plain JSON, HTML, and JavaScript. The core components use the optional Build Tools helpers at a larger scale, but nothing here depends on them.