Skip to content

FAQPage JSON-LD from accordion "FAQ Schema" contains unescaped control characters (invalid JSON) #982

Description

@helenakos

Plugin version: Kadence Blocks 3.7.0
WordPress version: 6.9.4

Description

When an Accordion block has the "FAQ Schema" option enabled, the plugin outputs a <script type="application/ld+json" class="kadence-faq-schema-graph"> block. The acceptedAnswer.text values contain raw newline characters (U+000A) instead of the escaped sequence \n. Per RFC 8259, control characters must be escaped inside JSON string literals, so the output is invalid JSON. Confirmed still present in 3.7.0.

Steps to reproduce

  1. Create a page with an Accordion block.
  2. In one pane, add an answer that contains a List block, or several block-level elements. Gutenberg inserts newline characters between the rendered blocks.
  3. Enable "FAQ Schema" on the Accordion block.
  4. View the page source and copy the kadence-faq-schema-graph JSON-LD.
  5. Run it through JSON.parse() or any strict JSON parser.

Expected

The JSON-LD parses cleanly. Control characters in acceptedAnswer.text are escaped — e.g. the value is produced via wp_json_encode() rather than string concatenation.

Actual

JSON.parse() throws Bad control character in string literal in JSON at position N. The first failure is typically at the <ul> / <li> boundary inside an answer.

Impact

Lenient parsers tolerate it — Google's Rich Results Test passes and detects all questions. But strict consumers reject the entire block. In our case the GTranslate translation proxy skips the schema entirely on translated pages because of this, so translated pages carry source-language FAQ schema instead of localized schema.

Example

A kadence-faq-schema-graph block whose first answer contains a list fails JSON.parse. Excerpt of the emitted JSON-LD, with the raw newline shown as an actual line break:

...</p><p>Some heading text:</p><ul>
<li>First list item</li>

The literal newline between <ul> and <li> should be \n in the JSON string. The same applies to the blank-line block separators Gutenberg inserts between paragraphs. Passing the whole answer HTML through wp_json_encode() would escape all control characters correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions