codeant-ai-for-open-source[bot] commented on code in PR #37404: URL: https://github.com/apache/superset/pull/37404#discussion_r2771838500
########## docs/src/components/FAQSchema.tsx: ########## @@ -0,0 +1,66 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import type { JSX } from 'react'; +import Head from '@docusaurus/Head'; + +interface FAQItem { + question: string; + answer: string; +} + +interface FAQSchemaProps { + faqs: FAQItem[]; +} + +/** + * Component that injects FAQPage JSON-LD structured data + * Use this on FAQ pages to enable rich snippets in search results + * + * @example + * <FAQSchema faqs={[ + * { question: "What is Superset?", answer: "Apache Superset is..." }, + * { question: "How do I install it?", answer: "You can install via..." } + * ]} /> + */ +export default function FAQSchema({ faqs }: FAQSchemaProps): JSX.Element | null { + // FAQPage schema requires a non-empty mainEntity array per schema.org specs + if (!faqs || faqs.length === 0) { + return null; + } + + const schema = { + '@context': 'https://schema.org', + '@type': 'FAQPage', + mainEntity: faqs.map((faq) => ({ + '@type': 'Question', + name: faq.question, + acceptedAnswer: { + '@type': 'Answer', + text: faq.answer, + }, + })), + }; + + return ( + <Head> + <script type="application/ld+json">{JSON.stringify(schema)}</script> Review Comment: **Suggestion:** The JSON-LD is injected as a child string of the script tag, which React will escape when rendering HTML; this can corrupt the JSON (e.g., by HTML-encoding characters) and cause search engines to ignore the structured data, so it should instead be written via `dangerouslySetInnerHTML` to preserve the exact JSON string. [possible bug] <details> <summary><b>Severity Level:</b> Major ⚠️</summary> ```mdx - ❌ FAQ structured data may be ignored by search engines. - ⚠️ FAQ page loses rich snippet eligibility. - ⚠️ Search visibility for documentation FAQ reduced. ``` </details> ```suggestion <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }} /> ``` <details> <summary><b>Steps of Reproduction ✅ </b></summary> ```mdx 1. Locate the FAQ schema component at docs/src/components/FAQSchema.tsx:42 (component definition) and note the render at lines 61-65 which places JSON.stringify(schema) as a child of the <script> element (file verified via Read of that path). 2. Find where the component is used: docs/docs/faq.mdx imports and renders FAQSchema (grep matches at docs/docs/faq.mdx:8 and docs/docs/faq.mdx:10; the import and usage lines were found in repository search output). 3. Build the site as in the project's test plan (run yarn build from repository root). Docusaurus will server-render the FAQ page that imports FAQSchema; the React render at docs/src/components/FAQSchema.tsx:61 will produce a <script> tag with the JSON as a React child node. 4. Inspect the generated HTML for the built FAQ page (e.g., build output file for that route). Because React escapes child text content, characters like '<' and '&' in the serialized JSON may be HTML-encoded in the output, causing the JSON-LD payload to be altered and potentially ignored by search engine parsers. 5. Reproduce the issue concretely by opening the built FAQ page's HTML and searching for the script tag content: instead of raw JSON-LD (exact JSON string), the script body shows HTML-escaped characters (evidence: component source at docs/src/components/FAQSchema.tsx:61 uses {JSON.stringify(schema)} as child). This demonstrates the rendering path and where the JSON becomes escaped. 6. Confirm impact by testing the page with a structured data tester (e.g., Google Rich Results Test) against the built HTML: the test will either not detect the expected FAQPage schema or will report invalid JSON if escaping has occurred. Note: The reproduction steps above are grounded in code locations discovered via repository Grep/Read (FAQSchema at docs/src/components/FAQSchema.tsx and usage at docs/docs/faq.mdx). The existing pattern (using a script child) leads to escaping on render; replacing with dangerouslySetInnerHTML at the same render site prevents React from escaping the JSON string. ``` </details> <details> <summary><b>Prompt for AI Agent 🤖 </b></summary> ```mdx This is a comment left during a code review. **Path:** docs/src/components/FAQSchema.tsx **Line:** 63:63 **Comment:** *Possible Bug: The JSON-LD is injected as a child string of the script tag, which React will escape when rendering HTML; this can corrupt the JSON (e.g., by HTML-encoding characters) and cause search engines to ignore the structured data, so it should instead be written via `dangerouslySetInnerHTML` to preserve the exact JSON string. Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise. ``` </details> -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
