FAQ Schema Markup | Wix Blogs

I’m having trouble with
I used to be able to toggle a collapsible list in blog posts to have FAQ schema markup like it is shown in this wix support article.

I can no longer find the toggle on collapsible list settings in the blogs.

My Questions:

  1. Does anyone know where this toggle went? I can’t get help from wix support. They all point to the above article.

  2. What are best practices for FAQ or How to schema markup for both internal pages and blog pages? I do have the wix FAQ app and am using it but it is not the most straightforward.

  3. Do I just need to learn how to code or do we think wix is going to address schema markup with further updates?

Yes i have that same problem with FAQ Schema. WIX dont generated those automatically even you have widget, so yo have to learn how to write those Schema codes

Hi, it’s just about a year after your initial post, and I’m going to vote for #3 - we’ll need to learn how to code the FAQ schema in the meantime. I just worked through this exact issue and wrote a pretty detailed blog post about what I learned. In the end, my solution is to use JavaScript to scrape the generated FAQs and create a schema.

I skipped Velo and instead put the JavaScript in the Wix Dashboard Custom Code Injection Panel. I didn’t use the variable classes (which change); instead, I added a custom class (.section-faq) to the FAQ accordion wrapper and looked for [data-hook="title"] and [data-id="content-viewer"].

Here’s the script:

<script>
(function() {
    function buildDynamicFaqSchema() {
        // 1. Target your stable custom structural container class anchor
        var targetSection = document.querySelector('.section-faq');
        if (!targetSection) return;

        // 2. Select all question headers using the unchangeable framework data-hook
        var questionNodes = targetSection.querySelectorAll('[data-hook="title"]');
        if (questionNodes.length === 0) return;

        var schemaArray = [];

        questionNodes.forEach(function(qNode) {
            var qText = qNode.innerText || qNode.textContent;
            
            // 3. Natively cross-reference the answer block safely without layout class guessing
            var rowItemContainer = qNode.closest('[data-hook="accordion-one-column-wrapper"]') || qNode.closest('[role="region"]') || qNode.parentElement.closest('div');
            if (!rowItemContainer) return;

            // Target the answer block inside this specific row using its native platform data identifier
            var aNode = rowItemContainer.querySelector('[data-id="content-viewer"]') || rowItemContainer.querySelector('[data-hook="accordion-item-content"]');
            if (!aNode) return;

            var aText = aNode.innerText || aNode.textContent;

            if (qText && aText && qText.trim().length > 3 && aText.trim().length > 10) {
                var cleanQ = qText.trim();
                
                // Prevent duplicate records from trailing into the final metadata arrays
                if (!schemaArray.some(function(i) { return i.name === cleanQ; })) {
                    schemaArray.push({
                        "@type": "Question",
                        "name": cleanQ,
                        "acceptedAnswer": {
                            "@type": "Answer",
                            "text": aText.trim().replace(/\s+/g, ' ')
                        }
                    });
                }
            }
        });

        // 4. Inject finalized clean data packets directly into the head container file
        if (schemaArray.length > 0) {
            var oldScript = document.getElementById('dynamic-faq-jsonld');
            if (oldScript) oldScript.remove();

            var scriptContainer = document.createElement('script');
            scriptContainer.id = 'dynamic-faq-jsonld';
            scriptContainer.type = 'application/ld+json';
            scriptContainer.text = JSON.stringify({
                "@context": "https://schema.org",
                "@type": "FAQPage",
                "mainEntity": schemaArray
            });

            document.head.appendChild(scriptContainer);
            console.log("Success: Immutable FAQ Schema generated and appended safely to document head!");
        }
    }

    // 5. Watch for the exact frame Wix's data-attribute markers attach to the window tree
    var layoutObserver = new MutationObserver(function(mutations, observer) {
        var widgetCoreHydrated = document.querySelector('[data-id="content-viewer"]');
        if (widgetCoreHydrated) {
            buildDynamicFaqSchema();
            observer.disconnect(); // Terminate observer loop right away to maintain light performance
        }
    });

    if (document.body) {
        layoutObserver.observe(document.body, { childList: true, subtree: true });
    }
    
    // Safety fallback layer to process heavily cached user networks
    window.addEventListener('load', function() {
        setTimeout(buildDynamicFaqSchema, 2000);
    });
})();
</script>

Add this via Settings > Custom Code on any page where your Wix FAQ app is active (placed in the Body - End). It automatically generates clean JSON-LD for your questions and stays up to date as you add, remove, or reorder FAQs in your dashboard. Happy coding!

More reference: Wix Studio vs. Squarespace: Cracking the React Hydration Layer to Automate FAQ Schema | Designer to Fullstack

The option to create an expandable list still exist :slight_smile:


And this is a cool solution @DesignerToFullstack! Thanks for sharing :flexed_biceps:

To add to this, it’s possible to add Structured data markup to individual blog posts

And is also possible per page via the SEO settings - Adding Structured Data Markup to Your Site's Pages | Help Center | Wix.com