Free FAQ Accordion Section for ShopifyNo app. Copy, paste, done.
- Online Store 2.0
- No app
- Theme Check: 0 errors
- MIT license
The Stackframes FAQ accordion is a free Shopify section you paste into your theme's code. It shows collapsible questions and answers that shoppers can open with a mouse or keyboard. It can also add FAQPage structured data so search engines understand your FAQs. It needs no app, adds no monthly fee, and every question and colour is editable in the theme editor.
Live preview with sample content. Once installed, fonts follow your theme and colours are editable in the theme editor.
{%- liquid
assign faq_group = 'sf-faq-' | append: section.id
assign has_items = false
for block in section.blocks
if block.settings.question != blank
assign has_items = true
break
endif
endfor
-%}
{%- if has_items or request.design_mode -%}
<sf-faq-accordion
class="sf-faq"
style="--sf-faq-text: {{ section.settings.text_color }}; --sf-faq-accent: {{ section.settings.accent_color }}; --sf-faq-bg: {{ section.settings.background_color }}; --sf-faq-pt: {{ section.settings.padding_top }}px; --sf-faq-pb: {{ section.settings.padding_bottom }}px;"
>
<div class="sf-faq__inner">
{%- if section.settings.heading != blank -%}
<h2 class="sf-faq__heading">{{ section.settings.heading | escape }}</h2>
{%- endif -%}
{%- if section.settings.intro != blank -%}
<div class="sf-faq__intro">{{ section.settings.intro }}</div>
{%- endif -%}
{%- if has_items -%}
<div class="sf-faq__list">
{%- for block in section.blocks -%}
{%- if block.settings.question == blank -%}{%- continue -%}{%- endif -%}
<details
class="sf-faq__item"
{% if section.settings.single_open %}name="{{ faq_group }}"{% endif %}
{% if forloop.first and section.settings.open_first %}open{% endif %}
{{ block.shopify_attributes }}
>
<summary class="sf-faq__question">
<span>{{ block.settings.question | escape }}</span>
<svg class="sf-faq__icon" aria-hidden="true" focusable="false" viewBox="0 0 20 20" width="20" height="20">
<path d="M5 7.5 10 12.5 15 7.5" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</summary>
<div class="sf-faq__answer">{{ block.settings.answer }}</div>
</details>
{%- endfor -%}
</div>
{%- else -%}
<p class="sf-faq__empty">Add a question block to show your FAQ.</p>
{%- endif -%}
</div>
</sf-faq-accordion>
{%- endif -%}
{%- if has_items and section.settings.output_schema -%}
{%- assign ld_started = false -%}
{%- capture ld_entries -%}
{%- for block in section.blocks -%}
{%- assign ld_question = block.settings.question | strip_html | strip -%}
{%- assign ld_answer = block.settings.answer | replace: '</p>', '</p> ' | strip_html | strip -%}
{%- if ld_question != blank and ld_answer != blank -%}
{%- if ld_started -%},{%- endif -%}
{
"@type": "Question",
"name": {{ ld_question | json }},
"acceptedAnswer": { "@type": "Answer", "text": {{ ld_answer | json }} }
}
{%- assign ld_started = true -%}
{%- endif -%}
{%- endfor -%}
{%- endcapture -%}
{%- if ld_started -%}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [{{ ld_entries }}]
}
</script>
{%- endif -%}
{%- endif -%}
{% stylesheet %}
.sf-faq { display: block; color: var(--sf-faq-text); background: var(--sf-faq-bg); padding: var(--sf-faq-pt) 20px var(--sf-faq-pb); }
.sf-faq__inner { max-width: 768px; margin: 0 auto; }
.sf-faq__heading { margin: 0 0 12px; font-size: clamp(24px, 19px + 1.2vw, 36px); line-height: 1.15; letter-spacing: -0.01em; }
.sf-faq__intro { margin: 0 0 24px; opacity: 0.8; }
.sf-faq__intro > :first-child { margin-top: 0; }
.sf-faq__intro > :last-child { margin-bottom: 0; }
.sf-faq__list { border-top: 1px solid color-mix(in srgb, currentColor 15%, transparent); }
.sf-faq__item { border-bottom: 1px solid color-mix(in srgb, currentColor 15%, transparent); }
.sf-faq__question { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 44px; padding: 1.1em 0; cursor: pointer; font-weight: 600; list-style: none; }
.sf-faq__question::-webkit-details-marker { display: none; }
.sf-faq__question:focus-visible { outline: 2px solid var(--sf-faq-accent); outline-offset: 4px; border-radius: 2px; }
.sf-faq__icon { flex: none; color: var(--sf-faq-accent); transition: transform 0.2s ease; }
.sf-faq__item[open] .sf-faq__icon { transform: rotate(180deg); }
.sf-faq__answer { padding: 0 0 20px; opacity: 0.85; }
.sf-faq__answer > :first-child { margin-top: 0; }
.sf-faq__answer > :last-child { margin-bottom: 0; }
.sf-faq__empty { margin: 0; padding: 24px; border: 1px dashed currentColor; border-radius: 8px; text-align: center; opacity: 0.7; }
@media (prefers-reduced-motion: reduce) { .sf-faq__icon { transition: none; } }
{% endstylesheet %}
{% javascript %}
if (!customElements.get('sf-faq-accordion')) {
class SfFaqAccordion extends HTMLElement {
connectedCallback() {
this.onBlockSelect = (event) => {
if (!this.contains(event.target)) return;
const item = event.target.closest('.sf-faq__item');
if (item) item.open = true;
};
document.addEventListener('shopify:block:select', this.onBlockSelect);
}
disconnectedCallback() {
document.removeEventListener('shopify:block:select', this.onBlockSelect);
}
}
customElements.define('sf-faq-accordion', SfFaqAccordion);
}
{% endjavascript %}
{% schema %}
{
"name": "SF FAQ accordion",
"tag": "section",
"class": "sf-faq-section",
"disabled_on": { "groups": ["header", "footer"] },
"max_blocks": 30,
"settings": [
{ "type": "text", "id": "heading", "label": "Heading", "default": "Frequently asked questions" },
{ "type": "richtext", "id": "intro", "label": "Intro text" },
{ "type": "checkbox", "id": "open_first", "label": "Open the first question", "default": true },
{ "type": "checkbox", "id": "single_open", "label": "Only one answer open at a time", "default": false },
{
"type": "checkbox",
"id": "output_schema",
"label": "Add FAQ structured data",
"info": "Adds FAQPage JSON-LD for search engines. Turn this off if another section on the same page already adds FAQ structured data.",
"default": true
},
{ "type": "header", "content": "Colors" },
{ "type": "color", "id": "text_color", "label": "Text", "default": "#121212" },
{ "type": "color", "id": "accent_color", "label": "Accent", "default": "#121212" },
{ "type": "color", "id": "background_color", "label": "Background", "default": "#ffffff" },
{ "type": "header", "content": "Spacing" },
{ "type": "range", "id": "padding_top", "label": "Top padding", "min": 0, "max": 100, "step": 4, "unit": "px", "default": 48 },
{ "type": "range", "id": "padding_bottom", "label": "Bottom padding", "min": 0, "max": 100, "step": 4, "unit": "px", "default": 48 }
],
"blocks": [
{
"type": "question",
"name": "Question",
"settings": [
{ "type": "text", "id": "question", "label": "Question", "default": "Do you ship internationally?" },
{ "type": "richtext", "id": "answer", "label": "Answer", "default": "<p>Yes. We ship to most countries, and duties and taxes are shown at checkout.</p>" }
]
}
],
"presets": [
{
"name": "SF FAQ accordion",
"blocks": [
{ "type": "question", "settings": { "question": "How long does shipping take?", "answer": "<p>Orders ship within 1–2 business days. Delivery usually takes 3–5 business days in the US.</p>" } },
{ "type": "question", "settings": { "question": "What is your return policy?", "answer": "<p>Unused items can be returned within 30 days for a full refund. Start a return from your order confirmation email.</p>" } },
{ "type": "question", "settings": { "question": "Do you ship internationally?", "answer": "<p>Yes. We ship to most countries, and duties and taxes are shown at checkout.</p>" } },
{ "type": "question", "settings": { "question": "How do I care for my product?", "answer": "<p>Wipe clean with a damp cloth and let it air dry. Avoid direct heat.</p>" } }
]
}
]
}
{% endschema %}
- Native <details> accordion — works even before JavaScript loads
- Optional FAQPage JSON-LD built from your questions
- "One open at a time" mode with no extra script
- Opens the selected question while you edit in the theme editor
- Colours and spacing editable in the theme editor
Add the FAQ Accordion to your theme
About two minutes. No app, no monthly fee.
Prefer a walkthrough? See the full installation guide.
- STEP 01
Duplicate your theme
In Shopify admin go to Online Store → Themes. Next to your current theme click ⋯ → Duplicate. Make every change on the copy.
- STEP 02
Create the section file
On the copy, click ⋯ → Edit code. In the sections folder click “Add a new section”, choose Liquid, name it sf-faq-accordion and create it. Delete the starter code, paste ours, then click Save.
- STEP 03
Add it to a page
Click Customize, open the template you want, click “Add section” and choose “SF FAQ accordion”. Edit the text, blocks and colours in the sidebar, then Save.
- STEP 04
Check it, then publish
Preview on mobile and desktop. When you are happy, publish the duplicate theme.
What you can change in the theme editor
| Setting | Type | Default |
|---|---|---|
| Heading | Text | Frequently asked questions |
| Intro text | Rich text | — |
| Open the first question | Checkbox | On |
| Only one answer open at a time | Checkbox | Off |
| Add FAQ structured dataAdds FAQPage JSON-LD for search engines. Turn this off if another section on the same page already adds FAQ structured data. | Checkbox | On |
| Text | Colour | #121212 |
| Accent | Colour | #121212 |
| Background | Colour | #ffffff |
| Top padding | Slider | 48px |
| Bottom padding | Slider | 48px |
| Setting | Type | Default |
|---|---|---|
| Question | Text | Do you ship internationally? |
| Answer | Rich text | Yes. We ship to most countries, and duties and taxes are shown at checkout. |
This section is one piece of a custom theme.
We design and build complete Shopify themes around your brand.
Common questions
Will this FAQ section show rich results in Google?
It adds valid FAQPage structured data, which helps search engines understand the content. Since 2023 Google only shows FAQ rich results for a small set of authoritative sites, so most stores should not expect the expanded result in search.
Can I add more than one FAQ section to a page?
Yes. Each instance works independently. If both add structured data, turn off "Add FAQ structured data" on all but one so the page has a single FAQPage block.
Does it work on product pages?
Yes. Add it to the product template in the theme editor. It is disabled in the header and footer groups only.
How many questions can I add?
Up to 30 question blocks per section.
More free sections
Size Chart Popup
Free size chart popup for Shopify product pages: a size guide button that opens an accessible dialog with your measurements table. Liquid code, no app.
Comparison Table
Free "us vs them" comparison table section for Shopify with check marks, text values and a highlighted column. Accessible HTML table, no app.
Trust Badges
Free trust badge section for Shopify: shipping, returns, secure checkout and support icons. Lightweight inline SVG, no JavaScript, no app.
All free Shopify sections
Get a Shopify theme built around your brand
Custom sections, a full theme build, or changes to the theme you already have. Tell us what your store needs and we'll scope it with you.
Not affiliated with or endorsed by Shopify Inc. Shopify is a trademark of Shopify Inc.