256 Kilobytes

FAQ Schema Generator

Articles in Search Engine Optimization | By Huevos Rancheros

Published | Last Update

Generate nice FAQ schema for your pages to boost SERP visibility

849 views, 2 RAMs, and 3 comments

Enter your FAQ Schema content:

Question 1 :
Answer :
 

What is FAQ Schema and how will it help your SEO? Here's some very relevant content:

 
Users Who Have Downloaded More RAM:
Hash Brown (11 months ago)
yottabyte (10 months ago)
🐏 ⨉ 2
Posted by Huevos Rancheros 11 months ago

Edit History

• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
• [2019-08-30 4:32 PDT] August R. Garcia (11 months ago)
• [2019-08-30 4:32 PDT] August R. Garcia (11 months ago)
• [2019-08-30 4:32 PDT] August R. Garcia (11 months ago)
• [2019-08-30 4:32 PDT] August R. Garcia (11 months ago)
• [2019-08-30 4:32 PDT] August R. Garcia (11 months ago)
• [2019-08-30 4:32 PDT] August R. Garcia (11 months ago)
• [2019-08-30 4:32 PDT] Huevos Rancheros (11 months ago)
🕓 Posted at 30 August, 2019 04:32 AM PDT

Profile Photo - Huevos Rancheros Huevos Rancheros Staff

I sell rare words

Profile Photo - August R. Garcia August R. Garcia LARPing as a Sysadmi... Portland, OR Site Owner

Pour Up:

<script type="application/ld+json">
{
	"@context": "https://schema.org",
	"@type": "FAQPage",
	"mainEntity": [{
		"@type": "Question",
		"name": "What's the deal with airplane peanuts?",
		"acceptedAnswer": {
			"@type": "Answer",
			"text": "The deal with airplane peanuts is that they are generally given out as complimentary refreshments on airlines."
		}
	}]
	}
</script>

Download more RAM. 🐏 ⨉ 0 Posted by August R. Garcia 11 months ago 🕓 Posted at 30 August, 2019 10:52 AM PDT

Sir, I can do you a nice SEO.

Profile Photo - August R. Garcia August R. Garcia LARPing as a Sysadmi... Portland, OR Site Owner

PHP function to generate FAQ schema:

// @param $arr - An associative array where each key is a question and each value is its answer
function arr_to_faq_schema($arr) {  
        // Prepare the base structure of the associative array, which will be converted to JSON
        $assoc = [
                "@context"   => "https://schema.org",
                "@type"      => "FAQPage"           ,
                "mainEntity" => [
                ],  
        ];  
        
        // Insert the questions into the 
        foreach ($arr as $question => $answer) {
                $assoc["mainEntity"][] = [
                        "@type" => "Question", 
                        "name"  => $question ,        
                        "acceptedAnswer" => [
                                "@type" => "Answer" , 
                                "text"  => $answer 
                        ]
                ];   
        } 

        // Convert the associative array to JSON and place it between the required
        // <script> tags 
        $json = json_encode($assoc); 
        return "<script type='application/ld+json'>$json</script>"; 
} 

// Prepare an associative array where each key is a question and each value is its answer 
$arr = [
        "What time is it?"                   => "It's 5 PM"              ,
        "When is Father's Day?"              => "Sunday, 16 June, 2019"  ,
        "What is an example of an HTML tag?" => "The <strong> tag."          
];  

// Echos the result into the webpage. Will not be visible (unless viewing the page source), since it is wrapped in <script> tags.  
echo arr_to_faq_schema($arr);                  

// Optional/For convenience - Echo the same content out into human-visible/readable HTML   
foreach ($arr as $question => $answer) {
        echo "<h3>" . htmlspecialchars($question) . "</h3>"; 
        echo "<p>"  . htmlspecialchars($answer  ) . "</p>" ;     
} 

Users Who Have Downloaded More RAM:
yottabyte (8 months ago)
🐏 ⨉ 1
Posted by August R. Garcia 9 months ago 🕓 Posted at 24 October, 2019 17:46 PM PDT

Sir, I can do you a nice SEO.

Profile Photo - August R. Garcia August R. Garcia LARPing as a Sysadmi... Portland, OR Site Owner

Another better PHP function used to generate FAQ schema:

// ***** ***** ****************** ***** ***** //
// ***** ***** *** FAQ Schema *** ***** ***** //
// ***** ***** ****************** ***** ***** //
// Helper function to create the FAQ schema 
// @param $html is a string of HTML. 
// @param $q_tag is the tag used to wrap the questions for the FAQ. 
//        Everything before the first $q_tag will be unchanged.
//        Everything after a $q_tag is found will be part of the answer 
//        until either another $q_tag is found or the HTML ends. 
function add_faq_schema($html, $q_tag="h4") {  

        // Load the HTML into a PHP DOMDocument object and make a new/empty object for the final output  
        libxml_use_internal_errors(true);
        $doc = new DOMDocument(); $doc->loadHTML("<?xml encoding='UTF-8'><div class='faq-schema'></div><div>$html</div>", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

        // Loop through the nodes and add the FAQ schema markup to all questions and answers
        $faq     = $doc->lastChild; 

        // Select the node used for the final output 
        $xpath   = new DOMXpath($doc);
        $new     = $xpath->query("//*[contains(@class, 'faq-schema')]")->item(0);

        foreach ($faq->childNodes as $node) {

                if ( $node->nodeName == $q_tag ) {

                        // Create a new parent/wrapper node/div for the question and its answer 
                        $wrap = $doc->createElement('div', ''                          );
                        $wrap->setAttribute("itemscope", NULL                          );
                        $wrap->setAttribute("itemprop" , "mainEntity"                  );
                        $wrap->setAttribute("itemtype" , "https://schema.org/Question" );

                        // Add the FAQ schema markup required to the H4 tag 
                        $node->setAttribute('itemprop', "name");

                        // Add the H4 to the wrapper node 
                        $clone = $node->cloneNode(true);  
                        $wrap->appendChild($clone);

                        // Create the two nested wrapper divs used for the answer 
                        $div_ans  = $doc->createElement('div', ''                          );
                        $div_ans->setAttribute("itemscope", NULL                           );
                        $div_ans->setAttribute("itemprop" , "acceptedAnswer"               );
                        $div_ans->setAttribute("itemtype" , "https://schema.org/Answer"    );

                        $div_text = $doc->createElement('div', ''                          );
                        $div_text->setAttribute("itemprop" , "text"                        );

                }

                // Loop through nodes until next H4. Add everything until the next h4 (or end of HTML) to the nested answer divs. 
                elseif (isset($wrap)) {

                        // Add this node to the inner answer div 
                        $clone = $node->cloneNode(true);
                        $div_text->appendChild($clone);

                        // If the next node is an <h4> or does not exist, then handle the final/full text for the answer of the previous one. 
                        if ( !$node->nextSibling || $node->nextSibling->nodeName == $q_tag ) {
                                $div_ans->appendChild($div_text); // Add the final answer to the answer inner wrapper   
                                $wrap->appendChild($div_ans);     // Add the inner answer wrapper to the outer wrapper   
                                $new->appendChild($wrap);         // Add the new node to the $new HTML to return         
                        }
                }

                // If there are any nodes before the first question, include them unchanged. 
                else {
                        $clone = $node->cloneNode(true);
                        $new->appendChild($clone);
                }
        }

        // Function defined in app/Helpers/InputHandling.php  
        return DOMinnerHTML($new);
}

// https://stackoverflow.com/questions/2087103/how-to-get-innerhtml-of-domnode  
function DOMinnerHTML(DOMNode $element) {
    $innerHTML = ""; 
    $children  = $element->childNodes;

    foreach ($children as $child) 
        $innerHTML .= $element->ownerDocument->saveHTML($child);
    return $innerHTML;
}

Example of use:

<?php
/*                      
 * faq-schema.blade.php
 * 
 * This is a wrapper file for FAQ section includes that will 
 * automatically process them to add FAQ schema. 
 * 
 * @param $include - Required - Self explanatory.
*/

// Allow for the storage of the input into a variable instead of into the output buffer 
ob_start();
?>               
@include($include)
<?php
        // Get the HTML for the section 
        $html = ob_get_contents();
        ob_end_clean();
                        
        // Add the altered HTML to the input buffer 
        echo add_faq_schema($html); 
?>

The @include($include) in the use example is with Laravel / the Blade templating library. Could easily be replaced with a normal PHP include. 

Download more RAM. 🐏 ⨉ 0 Posted by August R. Garcia 7 months ago

Edit History

• [2019-12-16 2:34 PST] August R. Garcia (7 months ago)
• [2019-12-16 2:34 PST] August R. Garcia (7 months ago)
🕓 Posted at 16 December, 2019 02:34 AM PST

Sir, I can do you a nice SEO.

Post a New Comment

To leave a comment, login to your account or create an account.

Do you like having a good time?

Register an Account

You can also login to an existing account or reset your password. All use of this site is subject to the terms of service and privacy policy.

Read Quality Articles

Read some quality articles. If you can manage to not get banned for like five minutes, you can even post your own articles.

View Articles →

Argue with People on the Internet

Use your account to explain why people are wrong on the Internet forum.

View Forum →

Vandalize the Wiki

Or don't. I'm not your dad.

View Wiki →

Ask and/or Answer Questions

If someone asks a terrible question, post a LMGTFY link.

View Answers →

Make Some Money

Hire freelancers and/or advertise your goods and/or services. Hire people directly. We're not a middleman or your dad. Manage your own business transactions.

Register an Account