Purpose#
The Faq component renders frequently asked questions as nested accordions:Groups (categories): optional, collapsible when the group has a title
FAQ lists inside each group: optional, collapsible when the list has a name
Questions inside each list: each question toggles its answer
Only one question is open at a time. Server-side pagination is supported through model.Pagination.
Where it's rendered#
Placed on a page as a regular component (Components/Faq/Default.liquid). The whole section renders only when model.Groups has at least one entry.
Model shape (storefront example)#
{
"name": "Faq",
"view": "Default",
"section": "SectionA",
"settings": {
"id": "Component Id",
"cssClass": "",
"header": "Sample title",
"alignment": "Left"
},
"groups": [
{
"title": "Sample category",
"faqs": [
{
"name": "Sample name",
"items": [
{ "question": "Sample question", "answer": "<p>Sample answer</p>" }
]
}
]
}
],
"pagination": {
"pageNumber": 1,
"numberOfPages": 3,
"pageParameterName": "faqPage"
},
"translations": {
"faq": "Sample translation",
"untitled": "Sample translation",
"pagination": "Sample translation",
"...": "..."
}
}
Required fields#
settings.id
Used for the wrapper id comp-{{ id }} and every toggle/panel id (comp-<id>-group-<n>, comp-<id>-list-<key>, comp-<id>-question-<key>).
groups
When empty, nothing is rendered.
Optional fields#
settings.cssClass
Applied only when non-empty and not (UNDEFINED).
settings.header
Rendered as an h2 above the groups; also used as the section aria-label (falls back to translations.faq).
settings.alignment
Center / Right / anything else (left) for the header block.
groups[].title
When empty, the group has no toggle and its lists are always visible.
groups[].faqs[].name
When empty, the list has no toggle and its questions are always visible.
pagination.pageNumber (default 1), pagination.numberOfPages, pagination.pageParameterName (default faqPage)
Pagination renders only when numberOfPages > 1.
Translations used by the template: faq, untitled, pagination, previousPage, nextPage, goToPageNumber, currentPageNumber. noQuestionsSelected and categories are defined in the component translations file.
Template behavior (Liquid + Alpine)#
Keys are built from loop indexes: group <g>, list <g>-<l>, question <g>-<l>-<q>. Merchant text is never interpolated into Alpine expressions.
Initial state is rendered server-side to avoid flicker: the first group and list 1-1 start open; every question starts closed.
Questions with both empty question and answer are skipped. An empty question falls back to translations.untitled.
answer is rendered as HTML.
Every toggle is a button with a bound :aria-expanded and aria-controls pointing to a role="region" panel.
Pagination uses the same sliding-window logic as CustomTable (at most 7 entries, with ... gaps); the current page is a span with aria-current="page".
JavaScript#
Global object#
x-data="faqdefault.initComponent(null, 1, '1-1', {{ pageParameterName | serialize | escape }})"
initComponent#
Returns the Alpine state: openKey (question), openGroup (group index), openList (list key) and pageParameterName. A single shared key per level is what makes opening one item close the other.
isOpen#
isOpen(key) returns true when the question key is open.
toggle#
toggle(key) opens the question key, or closes it if it is already open. Opening a question closes any other open question.
isListOpen#
isListOpen(key) returns true when the FAQ list key is open.
toggleList#
toggleList(key) opens or closes a FAQ list.Opening closes every other list, any group other than its own, and any question outside the list.
Its own questions stay closed.
isGroupOpen#
isGroupOpen(index) returns true when the group index is open.
toggleGroup#
toggleGroup(index) opens or closes a group.Opening closes every other group and any list or question outside it.
Its own lists stay closed.
goToPage#
goToPage(page) sets pageParameterName in the query string and performs a full navigation, so every page is server-rendered and linkable.
Notes#
The accordion state is not persisted; a page change resets it to the initial state.
Modified at 2026-10-06 10:08:41