FAQ From Metaobject

Section

Grouped FAQ tabs (JS-free radio pattern) driven by blocks with per-question tab assignment and FAQPage JSON-LD.

TextFreeSeo RichDynamic
Edit
Copied 0 times
Preview
Accent
Section code
<section class="sl-faq-metaobject" style="padding:clamp(32px,6vw,64px) 1rem;max-width:880px;margin:0 auto;color:inherit;font-family:inherit;">
  <h2 style="text-align:center;font-size:clamp(1.5rem,3vw,2rem);margin:0 0 1.5rem;">{{ section.settings.heading }}</h2>
  {%- assign tab_names = '' -%}
  {%- for block in section.blocks -%}{%- assign tab_names = tab_names | append: block.settings.tab_name | append: '||' -%}{%- endfor -%}
  {%- assign unique_tabs = tab_names | split: '||' | uniq -%}
  <style>
    .sl-gft-panel { display: none; }
    {%- for tab in unique_tabs -%}
      {%- assign tab_slug = tab | handle -%}
      #sl-gft-{{ section.id }}-{{ tab_slug }}:checked ~ .sl-gft-tabs label[for="sl-gft-{{ section.id }}-{{ tab_slug }}"] { background: var(--sl-accent,#0a5cff); color:#fff; border-color: var(--sl-accent,#0a5cff); }
      #sl-gft-{{ section.id }}-{{ tab_slug }}:checked ~ .sl-gft-panels [data-panel="{{ tab_slug }}"] { display: block; }
    {%- endfor -%}
  </style>
  {%- for tab in unique_tabs -%}
    {%- assign tab_slug = tab | handle -%}
    <input type="radio" name="sl-gft-{{ section.id }}" id="sl-gft-{{ section.id }}-{{ tab_slug }}" {% if forloop.first %}checked{% endif %} style="position:absolute;opacity:0;pointer-events:none;" />
  {%- endfor -%}
  <div class="sl-gft-tabs" role="tablist" style="display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center;margin:0 0 1.5rem;">
    {%- for tab in unique_tabs -%}
      {%- assign tab_slug = tab | handle -%}
      <label for="sl-gft-{{ section.id }}-{{ tab_slug }}" style="cursor:pointer;padding:.5rem 1rem;border:1px solid currentColor;border-radius:999px;font-size:.9rem;">{{ tab }}</label>
    {%- endfor -%}
  </div>
  <div class="sl-gft-panels">
    {%- for tab in unique_tabs -%}
      {%- assign tab_slug = tab | handle -%}
      <div class="sl-gft-panel" data-panel="{{ tab_slug }}">
        {%- for block in section.blocks -%}
          {%- if block.settings.tab_name == tab -%}
            <details style="border-bottom:1px solid currentColor;padding:1rem 0;" {{ block.shopify_attributes }}>
              <summary style="cursor:pointer;font-weight:600;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:1rem;">
                <span>{{ block.settings.question }}</span>
                <span style="color:var(--sl-accent,#0a5cff);font-size:1.25rem;">+</span>
              </summary>
              <div style="margin-top:.75rem;opacity:.85;line-height:1.6;">{{ block.settings.answer }}</div>
            </details>
          {%- endif -%}
        {%- endfor -%}
      </div>
    {%- endfor -%}
  </div>
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {%- for block in section.blocks -%}
      { "@type": "Question", "name": {{ block.settings.question | json }}, "acceptedAnswer": { "@type": "Answer", "text": {{ block.settings.answer | strip_html | json }} } }{%- unless forloop.last -%},{%- endunless -%}
      {%- endfor -%}
    ]
  }
  </script>
</section>
{% schema %}
{
  "name": "Grouped FAQ Tabs",
  "settings": [
    { "type": "text", "id": "heading", "label": "Heading", "default": "Frequently asked" }
  ],
  "blocks": [
    {
      "type": "item",
      "name": "FAQ item",
      "settings": [
        { "type": "text", "id": "tab_name", "label": "Tab name", "default": "General" },
        { "type": "text", "id": "question", "label": "Question", "default": "How long does shipping take?" },
        { "type": "richtext", "id": "answer", "label": "Answer", "default": "<p>Orders ship within 2 business days.</p>" }
      ]
    }
  ],
  "presets": [
    {
      "name": "Grouped FAQ Tabs",
      "blocks": [
        { "type": "item" },
        { "type": "item" },
        { "type": "item" },
        { "type": "item" }
      ]
    }
  ]
}
{% endschema %}

Internal notesTeam only

Freeform markdown notes visible only to signed-in team members. Separate from the public description.