Schema FAQPage JSON-LD: A 2026 Implementation Guide
Implement schema FAQPage JSON-LD the right way in 2026. Practical guide with snippets, validation, troubleshooting, and AI search tips.
The most popular advice about schema FAQPage JSON-LD is now wrong. Adding a few questions to a service or product page no longer represents a reliable way to win an expandable Google result. Google's current documentation says FAQ rich results will no longer appear in Search from 7 May 2026, and eligibility has already been limited to well-known, authoritative government and health websites in the documented transition. Google's FAQPage guidance and implementation context make the practical conclusion clear: French SMBs shouldn't deploy this markup as a guaranteed visibility shortcut.
That doesn't make the markup useless. It changes the job. A carefully implemented FAQPage entity gives machines a clean relationship between a question and its answer, while the visible page gives customers a readable explanation. For French ecommerce, local service, property, and professional websites, that structure can support content clarity, entity understanding, governance, and AI-oriented discoverability. It also creates an auditable contract between what the page says and what the structured data describes.
Why FAQPage JSON-LD Still Matters After the May 2026 Shift
FAQPage JSON-LD no longer earns its keep through a promised Google rich result. Google's documentation states that the FAQ search appearance is no longer shown from 7 May 2026, so deploying the markup as a free SERP visibility tactic is outdated. Google's structured-data update documentation points toward a more durable role: machine-readable content and clearer site understanding, rather than a guaranteed visual treatment.

The markup is still a description of the page
FAQPage JSON-LD fits pages built to answer several related questions. It labels each question, connects it to an accepted answer, and gives crawlers a consistent structure instead of making them infer relationships from accordions, layout, or decorative components.
That structure also has practical value for AI systems such as ChatGPT, Perplexity, and Gemini. There is no evidence here that these systems specifically prefer FAQPage JSON-LD over visible HTML, so guaranteed AI citations or automatic ranking gains are not a sound promise. The defensible position is narrower: clearly labelled question-and-answer pairs are easier to parse, audit, reuse, and compare than answers buried in unstructured prose.
Practical rule: Keep FAQPage when the page is an FAQ or when the FAQ content is central to the page. Remove the old rich-result expectation, not the requirement for accuracy.
For a French business, the benefit is operational. One maintained question set can align customer support, onsite content, internal search, structured data, and AI visibility monitoring. The implementation still depends on choosing the correct entity type, rendering markup in crawlable HTML, validating the output, and avoiding FAQPage where an FAQ is only an accessory.
Anatomy of a Valid FAQPage JSON-LD Block
A valid block starts with one JSON-LD entity. The canonical structure uses https://schema.org as the context, FAQPage as the type, and a mainEntity array containing multiple Question objects. French technical guidance published in 2026 describes the same foundation and recommends testing representative URLs, then monitoring impressions, clicks, CTR, and rankings before and after deployment as part of an SEO measurement process. The French technical JSON-LD reference also reflects Google's operational requirement that the page be accessible to crawlers and testable with inspection tools.
The core fields work like this:
@contextidentifies the vocabulary. Use"https://schema.org".@typeidentifies the page as"FAQPage".mainEntitycontains an array of questions, not a single question.Question.nameholds the exact visible question.acceptedAnswerconnects the question to its answer.Answer.textcontains the answer as one string.
The text value isn't a nested object. It can contain simple HTML such as <p>, <ul>, <li>, <a>, and <br>, but the output still needs to represent the answer clearly and safely. The page's visible content must match the markup. French guidance on FAQ synchronisation and editorial accuracy specifically stresses that Google expects the JSON-LD to mirror the FAQ shown to users.

A practical example for a French retailer might look like this:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Quels sont les délais de livraison en France ?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Les commandes sont expédiées après confirmation du paiement. Le délai applicable est indiqué au moment de la commande."
}
},
{
"@type": "Question",
"name": "Comment retourner un article ?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Contactez notre service client depuis la page dédiée aux retours, puis suivez les instructions communiquées pour organiser le renvoi de l’article."
}
}
]
}
</script>
For a broader explanation of implementation patterns across trades websites, JSON-LD for UK trades is a useful comparative resource. The important point is consistency. A page that visibly presents several questions and complete answers can support FAQPage. A page focused on one user-submitted question and its answer belongs to QAPage instead. For a practical discussion of the wider rich-result context, see the 2026 guide to Google rich snippets for SMEs.
Where the Markup Lives and How to Generate It Dynamically
Place FAQPage JSON-LD inside a single <script type="application/ld+json"> block. The document <head> is the cleanest location, although placing the block immediately before </body> also works when the server returns it as part of the initial HTML. French implementation guidance for FAQ schema describes the same pattern and treats a compact, maintainable question set as preferable to an uncontrolled block assembled from unrelated content.
Server-side rendering is the safest default. Your CMS, application, or template should build the mainEntity array and print the completed JSON-LD into the HTML response before a crawler needs to execute JavaScript. Client-side injection can work in some environments, but it introduces another dependency. A crawler or AI fetcher may receive the page before hydration, fail to execute the script, or encounter a JavaScript error that leaves the structured data absent.
Three reliable generation patterns
- CMS fields: Store each question and answer in a repeater or structured custom field. The template loops over published rows and serialises them with the platform's JSON encoder.
- Database records: Query the approved FAQ rows, filter out drafts and empty answers, then map each row to a
Questionobject before rendering. - Headless delivery: Have the server or API assemble the JSON-LD string and inject it during server-side rendering. Don't make the browser perform an extra fetch before the entity exists in the HTML.
The data source can change. The JSON structure shouldn't. Sanitize answer HTML, escape quotes correctly, and prevent editorial fields from introducing invalid JSON. Grumspot's Shopify structured-data tips offers useful platform-specific context, but the same principle applies to WordPress, custom PHP, Node, and headless frameworks: inspect the raw response, not only the browser's final DOM.
Ready-Made Templates for WordPress, Shopify, and Headless Stacks
Choose the template that matches your publishing stack, then adapt the data source rather than rewriting the schema model. These examples are intentionally compact. In production, use your platform's established escaping and sanitisation functions, and ensure the answers printed on the page are the same answers placed in JSON-LD.

WordPress with a repeater field
This functions.php pattern assumes an approved FAQ repeater field named faq_items. Replace the field accessors with those used by your CMS or plugin.
add_action('wp_footer', function () {
if (!is_page()) {
return;
}
$items = get_field('faq_items');
if (!$items || !is_array($items)) {
return;
}
$questions = [];
foreach ($items as $item) {
$question = wp_strip_all_tags($item['question'] ?? '');
$answer = wp_kses_post($item['answer'] ?? '');
if ($question === '' || $answer === '') {
continue;
}
$questions[] = [
'@type' => 'Question',
'name' => $question,
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => $answer,
],
];
}
if (!$questions) {
return;
}
$graph = [
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => $questions,
];
echo '<script type="application/ld+json">';
echo wp_json_encode($graph, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo '</script>';
});
For a static page, replace the field loop with a hardcoded PHP array. Keep the visible FAQ and the array under the same editorial workflow so an update can't change one without changing the other.
Shopify with page metafields
Shopify's exact Liquid syntax depends on the metafield definition. A simple approach stores each row as Question|Answer, then splits the value before output. The following pattern illustrates the structure, but test the metafield object in your theme before publishing.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{% for item in page.metafields.custom.faq_items.value %}
{% assign parts = item | split: "|" %}
{
"@type": "Question",
"name": {{ parts[0] | strip | json }},
"acceptedAnswer": {
"@type": "Answer",
"text": {{ parts[1] | strip | json }}
}
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]
}
</script>
Avoid using a separator that editors may place inside normal answers. A structured list of objects is safer than a delimited string when your Shopify setup supports it.
Headless rendering in Next.js
The essential requirement is that the script appears in the server response. A component can serialise the array during server rendering:
export default function FaqJsonLd({ faqItems }) {
const data = {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": faqItems.map(({ question, answer }) => ({
"@type": "Question",
"name": question,
"acceptedAnswer": {
"@type": "Answer",
"text": answer
}
}))
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
/>
);
}
Use plain text directly when the source stores plain text. When it stores HTML, sanitise it first and confirm that the rendered answer remains visible to users.
Validating Your Markup Before and After Deployment
Validation isn't a single button press. Treat it as a before-and-after check that compares the source code, the structured-data interpretation, and the live page.
Start with the rendered JSON-LD, not the CMS editor. Paste it into Google's Rich Results Test and the Schema Markup Validator to catch malformed JSON, missing properties, invalid nesting, and vocabulary issues. The technical audit workflow for ambitious SMEs can help you place this check alongside broader crawl and indexability reviews.

Before deployment, verify four things:
- Entity structure: There's one
FAQPageentity withmainEntityas an array. - Answer completeness: Every
Questionhas anacceptedAnswer, anAnswertype, and a text value. - Visible parity: The wording, order, and number of marked-up questions match the on-page FAQ.
- Crawlability: The URL isn't blocked by robots.txt,
noindex, login requirements, or an inaccessible template.
After publication, inspect the URL in Google Search Console and request indexing where appropriate. Use the rendered inspection to confirm Google can access the page, then compare it with the raw HTML returned by the server. A simple View Source check can reveal whether a JavaScript-only implementation failed to place the block in the initial response.
The following video provides a practical visual reference for structured-data testing. It should supplement, not replace, source inspection and page-content comparison.
Common Mistakes and How to Fix Them Fast
Most implementation failures are mundane. They come from a mismatch between editorial content, template behaviour, and crawler access rather than from complicated Schema.org logic.
Hidden answers that never reach the HTML
An accordion can be perfectly usable for people while still failing technically if the answer is loaded only after a click or fetched through JavaScript. Run curl or View Source and search for the question and answer text. Put the complete answer in the initial DOM, then mirror it in Answer.text.
Markup that says something different
A JSON-LD answer promising one return policy while the visible page shows another creates a trust and maintenance problem. Compare the rendered page with the script in the Rich Results Test, then make one source of truth feed both outputs.
One question inside FAQPage
FAQPage is intended for multiple questions and answers. If the page focuses on one question and one answer, use QAPage where the content fits that model. Don't force FAQPage around a single item because a plugin offers the option.
FAQPage attached to the wrong primary topic
A product page with a small FAQ section isn't automatically an FAQPage. The same applies to an article, service page, or how-to guide. If the questions aren't the page's central purpose, use accurate semantic HTML and avoid claiming that the entire page is a FAQ.
Access restrictions
Robots.txt rules, noindex, login barriers, or a templating condition can prevent crawlers from seeing the entity. Check the URL in Search Console, inspect the raw response, and review the page's meta robots directives before debugging the JSON itself.
Duplicate blocks from plugins
Two SEO plugins and a theme component may each print a separate FAQPage entity. Search the raw source for FAQPage, then merge the approved questions into one mainEntity array and disable the competing output.
FAQPage in a GEO Strategy for AI Search Engines
The right 2026 decision is not “Should every page have FAQPage?” It's “Does this page represent a multi-question knowledge resource that deserves a machine-readable Q&A layer?”
Use FAQPage when the page is built around customer questions, such as delivery and returns guidance, service eligibility, pricing explanations, property-process questions, or a clearly organised support resource. Keep the content editorial, specific, and visible. The French guidance recommends a practical range of 5 to 8 questions per page for maintainability and clarity, but that figure is a publishing convention, not a reason to add filler. The French FAQ schema implementation guide supports treating the question set as a coherent unit rather than a collection of unrelated additions.
Avoid it when the block is thin, duplicated across pages, programmatically generated without editorial review, or added only to chase a discontinued Google appearance. Choose QAPage for a page centred on one question-and-answer exchange. For ordinary product, article, and service pages with an attached FAQ, accurate headings, paragraphs, lists, and expandable HTML may describe the page more accurately than FAQPage.
That makes FAQPage one component of a broader GEO process, not a substitute for useful content. This practical explanation of GEO for SMEs places structured answers alongside entity consistency, content quality, and monitoring. AI systems may parse structured data, but they still need accessible pages, clear business facts, and corroborating signals before an answer becomes dependable.
Wispra helps French businesses monitor and improve how their company is represented across ChatGPT, Perplexity, Gemini, and Google AI through an AI-optimised directory, content tools, and visibility tracking. Review your FAQPage coverage alongside your wider AI presence, then visit Wispra to see how the platform can support that workflow.