XooCode(){

QAPage

QAPage is for community Q&A pages: one question asked by a user, with one or more answers from other users. Think Stack Overflow, Reddit, Quora, or a support forum thread. Google uses QAPage markup to display a Q&A rich result with the top answer or answer count directly in search results. This is different from FAQPage, which is for pages where the site owner publishes both the questions and the answers.

The structure nests three types: QAPage wraps a Question as its mainEntity, and the Question contains acceptedAnswer and/or suggestedAnswer entries. Each answer is an Answer object with its own author, text, date, and vote count. Google reads the accepted answer (if one exists) or the highest-voted suggested answer for the rich result snippet.

Full example of schema.org/QAPage json-ld markup

The markup is verified as valid with Rich Results Test from Google.

Highlight legend:Required by GoogleRecommendedOptional
schema.org/QAPage
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "QAPage",
  "@id": "https://community.xoocode.com/questions/xoostructured-nested-id-validation-error#QAPage",
  "name": "Why does XooStructured show a validation error on nested @id references?",
  "url": "https://community.xoocode.com/questions/xoostructured-nested-id-validation-error",
  "mainEntity": {
    "@type": "Question",
    "name": "Why does XooStructured show a validation error on nested @id references?",
    "text": "I have a Product block that references an Organization via @id, and the Organization references a PostalAddress via @id. XooStructured validates each block individually but flags a 'circular reference' warning on the Product. Is this a bug or am I structuring the @id chain wrong?",
    "dateCreated": "2026-03-20T09:14:00-05:00",
    "author": {
      "@type": "Person",
      "name": "Alex Kimura",
      "url": "https://community.xoocode.com/users/alex-kimura"
    },
    "answerCount": 3,
    "upvoteCount": 12,
    "about": {
      "@type": "SoftwareApplication",
      "@id": "https://xoocode.com/xoostructured#software"
    },
    "acceptedAnswer": {
      "@type": "Answer",
      "text": "Not a bug. XooStructured walks @id chains to verify that every reference resolves to a real block in the document. When it finds A references B references C references A, it flags a circular reference warning because infinite loops break some JSON-LD processors. Your structure is valid schema.org, but the circular chain is worth avoiding. Fix: give the PostalAddress its own @id and reference it directly from both Product and Organization instead of chaining through Organization.",
      "dateCreated": "2026-03-20T11:02:00-05:00",
      "author": {
        "@type": "Person",
        "name": "Tomás Herrera",
        "url": "https://community.xoocode.com/users/tomas-herrera"
      },
      "upvoteCount": 18
    },
    "suggestedAnswer": {
      "@type": "Answer",
      "text": "As a quick workaround, you can inline the PostalAddress directly in the Organization block instead of using @id for that level. The circular reference warning only triggers when three or more blocks form a loop via @id chains.",
      "dateCreated": "2026-03-20T12:30:00-05:00",
      "author": {
        "@type": "Person",
        "name": "Priya Reddy",
        "url": "https://community.xoocode.com/users/priya-reddy"
      },
      "upvoteCount": 7
    }
  }
}
</script>

acceptedAnswer vs suggestedAnswer

acceptedAnswer is the answer marked as correct or accepted by the question author (the green checkmark on Stack Overflow). suggestedAnswer is any other answer. A Question can have zero or one acceptedAnswer and any number of suggestedAnswers. Google prioritizes the acceptedAnswer for the rich result. If there is no accepted answer, Google may use the highest-voted suggestedAnswer instead.

QAPage vs FAQPage

The distinction is about who writes the answers. FAQPage is for editorially controlled pages where the site owner writes all Q&A pairs (like a product FAQ or help center). QAPage is for user-generated content where the community provides answers. Google renders them differently: FAQPage shows expandable Q&A pairs, QAPage shows a snippet of the top answer. Using the wrong type confuses the rich result and may trigger a manual action.

upvoteCount

upvoteCount is an integer on both Question and Answer objects representing the community vote score. Google reads this to select the best suggested answer when no accepted answer exists. Include the real vote count from your platform. Inflating the count does not help because Google cross-checks it against the page content.

answerCount

answerCount on the Question is the total number of answers the question has received. Like commentCount on BlogPosting, this is the total count, not the number of Answer objects in your markup. You can include a subset of answers in the markup while reporting the correct total.

Minimal valid version

The smallest markup that still produces a valid QAPage entity. Use it as the floor. Reach for the advanced example above when you want search engines and AI agents to understand more about your content.

schema.org/QAPage (minimal)
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "QAPage",
  "mainEntity": {
    "@type": "Question",
    "name": "Why does XooStructured show a validation error on nested @id references?",
    "answerCount": 3,
    "acceptedAnswer": {
      "@type": "Answer",
      "text": "XooStructured flags circular @id chains. Reference the PostalAddress directly from both blocks instead of chaining through Organization."
    }
  }
}
</script>

Google rich results this unlocks

Markup matching this example makes your page eligible for the following Google Search rich results. The primary target drives the required / recommended property classification in the advanced code block above.

Common QAPage mistakes

Mistakes that pass validation but silently fail to earn rich results or mislead consumers walking the graph. Avoid these and your markup will be ahead of most sites in the wild.

  1. 01

    Using QAPage for editorially controlled FAQ content

    Wrong
    QAPage markup on a company FAQ page where the site owner writes all questions and answers
    Right
    FAQPage for editorial Q&A, QAPage for community/user-generated Q&A

    Google enforces the distinction. QAPage is for pages where users submit questions and other users answer them. FAQPage is for pages where the site owner controls both sides. Using QAPage on a company FAQ may trigger a manual action because the content does not match the expected pattern.

  2. 02

    Multiple questions on a QAPage

    Wrong
    QAPage with mainEntity as an array of multiple Question objects
    Right
    QAPage with a single Question as mainEntity; use FAQPage for multiple Q&A pairs

    QAPage represents a single-question thread. One question, one or more answers. If the page has multiple questions (like a FAQ), use FAQPage instead. Putting multiple questions in a QAPage confuses the rich result and Google may ignore the markup.

  3. 03

    answerCount that doesn't match reality

    Wrong
    "answerCount": 2 when the page shows 3 answers
    Right
    "answerCount": 3 (matches the actual number of answers on the page)

    Google cross-checks answerCount against the visible page content. A mismatch signals that the structured data does not reflect the page, which can result in the rich result being suppressed. Report the real count.

  4. 04

    Omitting upvoteCount on answers

    Wrong
    Answer objects with text and author but no upvoteCount
    Right
    Each Answer with "upvoteCount": 18 (the real community vote score)

    When no acceptedAnswer exists, Google uses upvoteCount to pick the best suggestedAnswer for the rich result snippet. Without vote counts, Google has no ranking signal and may display a random answer or skip the rich result entirely.

  5. 05

    acceptedAnswer and suggestedAnswer on the same answer

    Wrong
    The same Answer object listed as both acceptedAnswer and in the suggestedAnswer array
    Right
    The accepted answer appears only in acceptedAnswer; other answers go in suggestedAnswer

    An answer is either accepted or suggested, not both. Duplicating it in both properties creates a confusing signal. If the question has an accepted answer, put it in acceptedAnswer and all other answers in suggestedAnswer.

About the example data

The thread is from a fictional Xoo Code community forum where a user asks why XooStructured shows a validation error on nested @id references. The accepted answer explains circular reference resolution, and a suggested answer offers a workaround. The about property references XooStructured via @id.

Comments

Loading comments...

Leave a comment