Skip to content

feat(marketing): improve GEO strategy for AI search visibility#1811

Closed
AviPeltz wants to merge 1 commit into
mainfrom
improve-geo-strategy-for-ai-search-visibility-impr
Closed

feat(marketing): improve GEO strategy for AI search visibility#1811
AviPeltz wants to merge 1 commit into
mainfrom
improve-geo-strategy-for-ai-search-visibility-impr

Conversation

@AviPeltz
Copy link
Copy Markdown
Collaborator

@AviPeltz AviPeltz commented Feb 25, 2026

Summary

  • Add keywords (10 targeted terms) and FAQ schema (3-5 Q&A pairs) to all 6 GEO-relevant blog posts
  • Add expanded keywords, FAQ frontmatter, and Related Comparisons sections with internal cross-links to all 10 comparison pages
  • Add BreadcrumbJsonLd and FAQPageJsonLd structured data to the compare detail page
  • Add faq field to ComparisonPage type and content parser
  • Add keywords to compare page <meta> tags
  • Fix roadmap-to-100-agents missing relatedSlugs, image, and weak description

+361 lines across 20 files. All pass lint and typecheck.

Test plan

  • Verify blog posts render correctly at /blog/<slug>
  • Verify compare pages render correctly at /compare/<slug>
  • Inspect page source to confirm BreadcrumbJsonLd and FAQPageJsonLd render on compare pages
  • Validate structured data with Google Rich Results Test
  • Confirm "Related Comparisons" links work on each 1v1 compare page
  • Confirm inline tool links work on the roundup page (/compare/best-ai-coding-agents-2026)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added FAQ sections to comparison pages with structured metadata for improved search visibility
  • Documentation

    • Enhanced blog posts with comprehensive FAQ sections and expanded keyword metadata across multiple topics
    • Expanded comparison pages with FAQs and cross-linked related content for better discoverability
    • Improved content structure and SEO optimization throughout marketing materials

Add keywords, FAQ schema, internal cross-linking, and breadcrumb
structured data across all marketing content to improve AI search
visibility for queries like "Cursor alternatives" and "best AI
coding tools 2026".

- Add keywords (10 terms) and FAQ (3-5 Q&A pairs) to 6 blog posts
- Add expanded keywords, FAQ, and Related Comparisons sections to all 10 compare pages
- Add BreadcrumbJsonLd and FAQPageJsonLd to compare detail page
- Add faq field to ComparisonPage type and parser
- Add keywords to compare page meta tags
- Fix roadmap-to-100-agents missing relatedSlugs, image, and description
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 25, 2026

📝 Walkthrough

Walkthrough

The PR enriches marketing content with SEO and engagement metadata across blog posts and comparison pages. Keywords, FAQ sections, and cross-references were added to content frontmatter. TypeScript utilities were updated to parse and render FAQ data as JSON-LD structured markup.

Changes

Cohort / File(s) Summary
Blog Post Metadata
apps/marketing/content/blog/agent-orchestration-not-another-agent.mdx, parallel-coding-agents-guide.mdx, terminal-daemon-deep-dive.mdx, roadmap-to-100-agents.mdx, git-worktrees-history-deep-dive.mdx, working-with-worktrees-in-superset.mdx
Added keywords lists and FAQ sections with structured Q&A pairs. Updated relatedSlugs references and appended narrative content blocks explaining architectural decisions and feature relevance.
Comparison Page Metadata
apps/marketing/content/compare/best-ai-coding-agents-2026.mdx, superset-vs-claude-code.mdx, superset-vs-codex.mdx, superset-vs-conductor.mdx, superset-vs-cursor.mdx, superset-vs-devin.mdx, superset-vs-github-copilot.mdx, superset-vs-opencode.mdx, superset-vs-warp.mdx, superset-vs-windsurf.mdx
Added keyword entries and FAQ blocks with comparative questions. Appended Related Comparisons sections with cross-linking to other comparison pages.
Type System & Rendering
apps/marketing/src/lib/compare-utils.ts, apps/marketing/src/lib/compare.ts, apps/marketing/src/app/compare/[slug]/page.tsx
Extended ComparisonPage interface with optional faq field. Updated parser to extract FAQ data from frontmatter. Added BreadcrumbJsonLd and FAQPageJsonLd imports and conditional rendering for structured data; added keywords to page metadata output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Possibly related PRs

Poem

🐰 Whiskers twitching with delight,
FAQs and keywords shining bright,
Cross-linked pages, hop by hop,
Content structured, never to stop!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main change: enhancing SEO/GEO strategy through structured data and keywords across marketing content pages.
Description check ✅ Passed The PR description provides comprehensive detail on changes, rationale, test plan, and scope alignment with the template structure and repository standards.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch improve-geo-strategy-for-ai-search-visibility-impr

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/marketing/content/compare/superset-vs-opencode.mdx (1)

5-5: ⚠️ Potential issue | 🟡 Minor

lastUpdated should be bumped when adding substantive content.

Line 5 still reads lastUpdated: 2026-02-02 despite the addition of a FAQ block and a Related Comparisons section — two meaningful content changes. For a page explicitly optimised for AI-search freshness signals, a stale lastUpdated date undercuts the PR's stated GEO goal.

📅 Proposed fix
-lastUpdated: 2026-02-02
+lastUpdated: 2026-02-25

Also applies to: 18-24

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/compare/superset-vs-opencode.mdx` at line 5, Update
the frontmatter key lastUpdated to today's date (2026-02-25) to reflect the
added FAQ and Related Comparisons content; locate the lastUpdated frontmatter
entry (symbol: lastUpdated) near the top of the document and replace the old
date, and also scan the file for any other lastUpdated occurrences (notably the
block around lines 18-24) and update them consistently.
🧹 Nitpick comments (4)
apps/marketing/content/compare/superset-vs-opencode.mdx (1)

18-24: FAQ frontmatter and body FAQ section can silently diverge.

The three Q&A pairs in the faq frontmatter (lines 19–24) are exact duplicates of the prose at lines 102–112. This is intentional — frontmatter feeds the JSON-LD renderer; the body is human-readable — but there is no guard preventing the two from drifting on future edits. Consider adding a brief comment near the body FAQ section (or a contributing note) that reminds editors to keep both in sync.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/compare/superset-vs-opencode.mdx` around lines 18 -
24, The frontmatter "faq" array duplicates the human-readable FAQ in the
document body, which can drift; add a short comment or contributing note
adjacent to the body FAQ (the prose block containing the three Q&A pairs)
reminding editors to update both the frontmatter "faq" and the body FAQ
together, e.g., "Keep the frontmatter 'faq' and body FAQ in sync" so future
edits don't diverge; place the comment immediately above the body FAQ section to
make it visible to contributors.
apps/marketing/content/compare/best-ai-coding-agents-2026.mdx (1)

26-29: New keyword additions look good; consider whether aider alternatives and opencode alternatives warrant inclusion.

Lines 26–29 round out the "alternatives" keyword coverage for all competitors entries except aider and opencode. If those terms have meaningful search volume, adding them would make the list exhaustive.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/compare/best-ai-coding-agents-2026.mdx` around lines
26 - 29, The alternatives list currently includes "windsurf alternatives",
"devin alternatives", "github copilot alternatives", and "conductor
alternatives" but omits "aider alternatives" and "opencode alternatives"; update
the alternatives array/section in the file (the list around the block containing
those four items) to add "aider alternatives" and "opencode alternatives" if
keyword research shows meaningful volume, ensuring the new entries follow the
same formatting and ordering as the existing competitor alternatives.
apps/marketing/src/lib/compare-utils.ts (1)

19-19: Consider extracting FaqEntry as a named exported type.

The inline { question: string; answer: string } shape will be needed wherever FAQPageJsonLd is constructed (e.g., page.tsx). Exporting a named type avoids duplication if that shape is referenced in multiple places.

♻️ Proposed refactor
+export interface FaqEntry {
+  question: string;
+  answer: string;
+}
+
 export interface ComparisonPage {
   ...
-  faq?: Array<{ question: string; answer: string }>;
+  faq?: FaqEntry[];
   content: string;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/src/lib/compare-utils.ts` at line 19, Extract the inline FAQ
item shape into a named exported type (e.g., export type FaqEntry = { question:
string; answer: string }) and replace the inline usage in the faq property
(faq?: Array<{ question: string; answer: string }>) with faq?: FaqEntry[] so
other modules (like where FAQPageJsonLd is constructed in page.tsx) can import
and reuse the type; ensure the new FaqEntry is exported from the same module and
update any imports/usages accordingly.
apps/marketing/content/blog/roadmap-to-100-agents.mdx (1)

27-27: Consider splitting the multi-part FAQ answer into bullet points or separate Q&A entries.

The answer for "How does Superset plan to scale to 100 parallel agents?" packs three distinct strategies into one inline-numbered string. Structured FAQ markup should match visible page content verbatim or near-verbatim, so if this answer is also rendered on-page, the inline (1)/(2)/(3) format is harder to read than a short list. Splitting into three separate Q&A pairs (or using the three strategies as the answer for this single question on the page with a list) would improve both readability and the quality of the emitted JSON-LD Answer.text field.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/blog/roadmap-to-100-agents.mdx` at line 27, The FAQ
answer for "How does Superset plan to scale to 100 parallel agents?" currently
contains a single inline-numbered string; replace that inline "(1)/(2)/(3)"
sentence with either a short markdown list or three separate Q&A entries so the
rendered page and emitted JSON-LD Answer.text match the visible structure.
Locate the answer string in roadmap-to-100-agents.mdx (the answer for that
specific question) and change it to one of: a) a multiline markdown list with
three bullet items describing the three strategies, or b) split into three
distinct question/answer blocks each containing one strategy; ensure formatting
is preserved in the MDX so the on-page output and JSON-LD include the readable
list or separate answers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/marketing/content/blog/git-worktrees-history-deep-dive.mdx`:
- Around line 22-32: The BlogPostLayout currently only outputs post.faq into
JSON-LD and never renders it; update BlogPostLayout to render post.faq as
visible DOM (e.g., an accordion) before the footer by reusing or extending the
existing FAQSection component: modify FAQSection to accept a prop like items
(falling back to existing FAQ_ITEMS) and then pass post.faq from BlogPostLayout
(the same post object used in blog/[slug]/page.tsx) into FAQSection so the
frontmatter FAQ is displayed on-page for all posts in this PR.

In `@apps/marketing/content/compare/best-ai-coding-agents-2026.mdx`:
- Around line 41-42: The frontmatter faq contains a sixth item ("What is the
best free AI coding tool?") that has no matching visible body section, causing
Google structured-data validation to fail; either add a visible FAQ entry with
the exact question and its answer to the page body (create a new "### What is
the best free AI coding tool?" section after the existing FAQ headings and paste
the same answer text) or remove that sixth item from the frontmatter JSON-LD so
the frontmatter faq array matches the five visible "###" headings exactly.

In `@apps/marketing/content/compare/superset-vs-codex.mdx`:
- Around line 24-25: Update the frontmatter FAQ entry for the question "How does
cloud Codex compare to Superset?" so the answer value matches the visible page
body by appending the missing closing sentence "They serve different trust and
infrastructure models." to the existing frontmatter answer string; locate the
frontmatter key question: "How does cloud Codex compare to Superset?" and modify
its corresponding answer field to exactly mirror the body content.

In `@apps/marketing/content/compare/superset-vs-devin.mdx`:
- Around line 18-26: Reorder the frontmatter "faq" array so its question
sequence matches the visible body FAQ order: move the "Is Superset open source?"
item to come before "Which is better for security-sensitive codebases?" (i.e.,
ensure the questions "Is Superset open source?" and "Which is better for
security-sensitive codebases?" appear in the same order in the frontmatter `faq`
array as they do in the rendered body); update the `faq` array in the file so
the question strings exactly match the body copy to avoid structured-data
mismatches.

In `@apps/marketing/src/lib/compare.ts`:
- Line 34: Validate the frontmatter value `data.faq` before assigning it to the
`ComparisonPage` object: implement a small validation check (e.g., a
`validateFaqFrontmatter` helper or a Zod schema) that ensures `data.faq` is the
expected type (array of Q/A objects or a properly shaped object with required
fields like `question` and `answer`), and only set `faq: data.faq` when the
validation passes; otherwise set `faq` to undefined or an empty array to avoid
rendering/JSON-LD errors. Ensure you call this validator where `faq: data.faq`
is assigned in compare.ts and use the validated value for the `ComparisonPage`
payload.

---

Outside diff comments:
In `@apps/marketing/content/compare/superset-vs-opencode.mdx`:
- Line 5: Update the frontmatter key lastUpdated to today's date (2026-02-25) to
reflect the added FAQ and Related Comparisons content; locate the lastUpdated
frontmatter entry (symbol: lastUpdated) near the top of the document and replace
the old date, and also scan the file for any other lastUpdated occurrences
(notably the block around lines 18-24) and update them consistently.

---

Nitpick comments:
In `@apps/marketing/content/blog/roadmap-to-100-agents.mdx`:
- Line 27: The FAQ answer for "How does Superset plan to scale to 100 parallel
agents?" currently contains a single inline-numbered string; replace that inline
"(1)/(2)/(3)" sentence with either a short markdown list or three separate Q&A
entries so the rendered page and emitted JSON-LD Answer.text match the visible
structure. Locate the answer string in roadmap-to-100-agents.mdx (the answer for
that specific question) and change it to one of: a) a multiline markdown list
with three bullet items describing the three strategies, or b) split into three
distinct question/answer blocks each containing one strategy; ensure formatting
is preserved in the MDX so the on-page output and JSON-LD include the readable
list or separate answers.

In `@apps/marketing/content/compare/best-ai-coding-agents-2026.mdx`:
- Around line 26-29: The alternatives list currently includes "windsurf
alternatives", "devin alternatives", "github copilot alternatives", and
"conductor alternatives" but omits "aider alternatives" and "opencode
alternatives"; update the alternatives array/section in the file (the list
around the block containing those four items) to add "aider alternatives" and
"opencode alternatives" if keyword research shows meaningful volume, ensuring
the new entries follow the same formatting and ordering as the existing
competitor alternatives.

In `@apps/marketing/content/compare/superset-vs-opencode.mdx`:
- Around line 18-24: The frontmatter "faq" array duplicates the human-readable
FAQ in the document body, which can drift; add a short comment or contributing
note adjacent to the body FAQ (the prose block containing the three Q&A pairs)
reminding editors to update both the frontmatter "faq" and the body FAQ
together, e.g., "Keep the frontmatter 'faq' and body FAQ in sync" so future
edits don't diverge; place the comment immediately above the body FAQ section to
make it visible to contributors.

In `@apps/marketing/src/lib/compare-utils.ts`:
- Line 19: Extract the inline FAQ item shape into a named exported type (e.g.,
export type FaqEntry = { question: string; answer: string }) and replace the
inline usage in the faq property (faq?: Array<{ question: string; answer: string
}>) with faq?: FaqEntry[] so other modules (like where FAQPageJsonLd is
constructed in page.tsx) can import and reuse the type; ensure the new FaqEntry
is exported from the same module and update any imports/usages accordingly.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8512d6 and bd63b64.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (19)
  • apps/marketing/content/blog/agent-orchestration-not-another-agent.mdx
  • apps/marketing/content/blog/git-worktrees-history-deep-dive.mdx
  • apps/marketing/content/blog/parallel-coding-agents-guide.mdx
  • apps/marketing/content/blog/roadmap-to-100-agents.mdx
  • apps/marketing/content/blog/terminal-daemon-deep-dive.mdx
  • apps/marketing/content/blog/working-with-worktrees-in-superset.mdx
  • apps/marketing/content/compare/best-ai-coding-agents-2026.mdx
  • apps/marketing/content/compare/superset-vs-claude-code.mdx
  • apps/marketing/content/compare/superset-vs-codex.mdx
  • apps/marketing/content/compare/superset-vs-conductor.mdx
  • apps/marketing/content/compare/superset-vs-cursor.mdx
  • apps/marketing/content/compare/superset-vs-devin.mdx
  • apps/marketing/content/compare/superset-vs-github-copilot.mdx
  • apps/marketing/content/compare/superset-vs-opencode.mdx
  • apps/marketing/content/compare/superset-vs-warp.mdx
  • apps/marketing/content/compare/superset-vs-windsurf.mdx
  • apps/marketing/src/app/compare/[slug]/page.tsx
  • apps/marketing/src/lib/compare-utils.ts
  • apps/marketing/src/lib/compare.ts

Comment on lines +22 to +32
faq:
- question: "What are Git worktrees and when were they introduced?"
answer: "Git worktrees are a feature introduced in Git 2.5 (July 2015) that lets you check out multiple branches simultaneously in separate working directories, all sharing the same git object store. They were primarily authored by Nguyễn Thái Ngọc Duy."
- question: "Why are Git worktrees suddenly popular in 2026?"
answer: "AI coding agents need isolated environments to work without conflicting. Worktrees provide filesystem-level isolation — each agent gets its own directory, branch, and staging area while sharing the git history. This pattern of parallel human + AI work is driving a resurgence in worktree adoption."
- question: "What's the difference between Git worktrees and cloning a repo twice?"
answer: "Worktrees share the git object store (commits, trees, blobs), so they take seconds to create and use minimal disk space. Separate clones duplicate the entire history, take minutes to create, and require push/pull to synchronize. Worktrees also share branches and tags natively."
- question: "Can the same branch be checked out in multiple Git worktrees?"
answer: "No. Git enforces a one-branch-per-worktree rule to prevent confusing bugs where commits in one worktree would cause unexpected dirty diffs in another. You can work around this with detached HEAD or by creating a new branch."
- question: "How do Git worktrees work under the hood?"
answer: "When you create a worktree, git creates a new directory with a .git file (not directory) pointing back to the main repo. The main repo stores worktree metadata in .git/worktrees/<name>/ with separate HEAD, index, and reflog files. Shared resources like objects and refs are resolved via the commondir mechanism."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find blog-related template/layout files
fd --type f \( -name "*.tsx" -o -name "*.jsx" -o -name "*.ts" \) "blog" apps/marketing/src 2>/dev/null | head -20

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

#!/bin/bash
# Search for files with names containing blog-related patterns
fd --type f \( -name "*blog*" -o -name "*BlogPost*" -o -name "*blog-post*" -o -name "*Post*" \) \( -name "*.tsx" -o -name "*.jsx" \) apps/marketing/src 2>/dev/null

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

#!/bin/bash
# Look for MDX layout configuration or template files
find apps/marketing -name "*.tsx" -o -name "*.jsx" | xargs grep -l "faq\|FAQ" 2>/dev/null | head -20

Repository: superset-sh/superset

Length of output: 294


🏁 Script executed:

cat -n apps/marketing/src/app/blog/[slug]/page.tsx

Repository: superset-sh/superset

Length of output: 3838


🏁 Script executed:

cat -n apps/marketing/src/app/components/FAQSection/FAQSection.tsx

Repository: superset-sh/superset

Length of output: 3050


🏁 Script executed:

find apps/marketing/src -name "BlogPostLayout*" -type f

Repository: superset-sh/superset

Length of output: 143


🏁 Script executed:

grep -r "post\.faq" apps/marketing/src --include="*.tsx" --include="*.ts"

Repository: superset-sh/superset

Length of output: 182


🏁 Script executed:

cat -n apps/marketing/src/app/blog/[slug]/components/BlogPostLayout/BlogPostLayout.tsx

Repository: superset-sh/superset

Length of output: 6665


🏁 Script executed:

grep -r "faq:" apps/marketing/content/blog --include="*.mdx" | head -5

Repository: superset-sh/superset

Length of output: 395


🏁 Script executed:

git diff --name-only HEAD~1 2>/dev/null | grep -c "apps/marketing/content/blog" || echo "0"

Repository: superset-sh/superset

Length of output: 67


Add visible FAQ section to blog post template.

FAQ content from frontmatter is currently only rendered as a JSON-LD <script> block (blog/[slug]/page.tsx, line 72). Google's structured data guidelines require FAQ schema to have corresponding visible on-page content.

The BlogPostLayout component does not render post.faq as visible DOM elements. While a FAQSection component exists, it uses hardcoded FAQ_ITEMS from constants, not frontmatter data.

Update BlogPostLayout to render post.faq visibly (e.g., accordion section) before the footer. This applies to all five blog posts in this PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/blog/git-worktrees-history-deep-dive.mdx` around lines
22 - 32, The BlogPostLayout currently only outputs post.faq into JSON-LD and
never renders it; update BlogPostLayout to render post.faq as visible DOM (e.g.,
an accordion) before the footer by reusing or extending the existing FAQSection
component: modify FAQSection to accept a prop like items (falling back to
existing FAQ_ITEMS) and then pass post.faq from BlogPostLayout (the same post
object used in blog/[slug]/page.tsx) into FAQSection so the frontmatter FAQ is
displayed on-page for all posts in this PR.

Comment on lines +41 to +42
- question: "What is the best free AI coding tool?"
answer: "For agents, OpenCode (MIT license, 75+ providers) and Codex CLI (Apache 2.0) are fully free and open source — you only pay for API usage. For orchestration, Superset has a free tier. For inline completions, GitHub Copilot has a free tier with limited requests."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Sixth FAQ item in frontmatter has no matching visible body section — will fail Google's structured data validation.

The body's FAQ section (lines 188–208) contains exactly five ### headings. The frontmatter faq block has six items; this sixth entry — "What is the best free AI coding tool?" — exists only in the JSON-LD markup but not in the visible page content.

Google's FAQPage structured data guidelines explicitly require that every question and answer in the markup must be visible to users on the page. A mismatch here can cause the Rich Results Test to report an error and disqualify the page from FAQ rich results.

Either add the matching visible section to the body, or remove the sixth item from the frontmatter.

📝 Option A — add the missing visible section to the body (after line 208)
 ### Which tool is most private?

 Superset and OpenCode are both open source and run locally with no telemetry. Codex CLI is open source but requires OpenAI API calls. Cursor, Windsurf, Devin, and Copilot all route code through external servers.
+
+### What is the best free AI coding tool?
+
+For agents, OpenCode (MIT license, 75+ providers) and Codex CLI (Apache 2.0) are fully free and open source — you only pay for API usage. For orchestration, Superset has a free tier. For inline completions, GitHub Copilot has a free tier with limited requests.
📝 Option B — drop the sixth item from the frontmatter
   - question: "Which AI coding tool is most private?"
     answer: "Superset and OpenCode are both open source and run locally with no telemetry. Codex CLI is open source but requires OpenAI API calls. Cursor, Windsurf, Devin, and Copilot all route code through external servers."
-  - question: "What is the best free AI coding tool?"
-    answer: "For agents, OpenCode (MIT license, 75+ providers) and Codex CLI (Apache 2.0) are fully free and open source — you only pay for API usage. For orchestration, Superset has a free tier. For inline completions, GitHub Copilot has a free tier with limited requests."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/compare/best-ai-coding-agents-2026.mdx` around lines
41 - 42, The frontmatter faq contains a sixth item ("What is the best free AI
coding tool?") that has no matching visible body section, causing Google
structured-data validation to fail; either add a visible FAQ entry with the
exact question and its answer to the page body (create a new "### What is the
best free AI coding tool?" section after the existing FAQ headings and paste the
same answer text) or remove that sixth item from the frontmatter JSON-LD so the
frontmatter faq array matches the five visible "###" headings exactly.

Comment on lines +24 to +25
- question: "How does cloud Codex compare to Superset?"
answer: "Cloud Codex runs in OpenAI's VMs and produces pull requests. Superset runs agents locally in Git worktrees. Cloud Codex offloads compute but sends code to OpenAI's servers. Superset keeps everything local with zero telemetry."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

FAQ answer in frontmatter is truncated compared to the body.

The frontmatter answer for "How does cloud Codex compare to Superset?" is missing the closing sentence present in the body at line 121: "They serve different trust and infrastructure models." Google's Rich Results Test validates that JSON-LD FAQ answers match visible page content; a mismatch here could cause validation failures.

🔧 Sync frontmatter answer to match body
-    answer: "Cloud Codex runs in OpenAI's VMs and produces pull requests. Superset runs agents locally in Git worktrees. Cloud Codex offloads compute but sends code to OpenAI's servers. Superset keeps everything local with zero telemetry."
+    answer: "Cloud Codex runs in OpenAI's VMs and produces pull requests. Superset runs agents locally in Git worktrees. Cloud Codex offloads compute but sends code to OpenAI's servers. Superset keeps everything local with zero telemetry. They serve different trust and infrastructure models."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- question: "How does cloud Codex compare to Superset?"
answer: "Cloud Codex runs in OpenAI's VMs and produces pull requests. Superset runs agents locally in Git worktrees. Cloud Codex offloads compute but sends code to OpenAI's servers. Superset keeps everything local with zero telemetry."
- question: "How does cloud Codex compare to Superset?"
answer: "Cloud Codex runs in OpenAI's VMs and produces pull requests. Superset runs agents locally in Git worktrees. Cloud Codex offloads compute but sends code to OpenAI's servers. Superset keeps everything local with zero telemetry. They serve different trust and infrastructure models."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/compare/superset-vs-codex.mdx` around lines 24 - 25,
Update the frontmatter FAQ entry for the question "How does cloud Codex compare
to Superset?" so the answer value matches the visible page body by appending the
missing closing sentence "They serve different trust and infrastructure models."
to the existing frontmatter answer string; locate the frontmatter key question:
"How does cloud Codex compare to Superset?" and modify its corresponding answer
field to exactly mirror the body content.

Comment on lines +18 to +26
faq:
- question: "Can Devin and Superset work together?"
answer: "They serve different workflows. Devin is a cloud-based autonomous engineer. Superset is a local agent orchestrator. You might use Devin for fully autonomous background tasks and Superset for interactive parallel work where you want more control."
- question: "Is Devin worth the price premium?"
answer: "Devin's $500/seat/month buys full autonomy: assign tasks via Slack, get PRs back. If your workflow benefits from hands-off delegation and you have the budget, it can be valuable. If you prefer direct control and cost efficiency, Superset at $20/seat/month plus API costs delivers more throughput per dollar."
- question: "Which is better for security-sensitive codebases?"
answer: "Superset. Code never leaves your machine. Devin runs code on Cognition's cloud infrastructure. For regulated industries, government work, or sensitive IP, local execution is a hard requirement."
- question: "Is Superset open source?"
answer: "Yes. Superset is open source under Apache 2.0 with zero telemetry. Devin is closed source from Cognition."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

FAQ frontmatter order doesn't match the body FAQ order.

The frontmatter lists the security question before the open-source question (3rd, 4th), but the body FAQ section has them reversed (open-source 3rd, security 4th). Google's Rich Results Test can flag discrepancies between FAQPageJsonLd structured data and the visible HTML content when question order diverges.

🔧 Align frontmatter FAQ order to match body
   - question: "Is Devin worth the price premium?"
     answer: "Devin's $500/seat/month buys full autonomy: ..."
+  - question: "Is Superset open source?"
+    answer: "Yes. Superset is open source under Apache 2.0 with zero telemetry. Devin is closed source from Cognition."
   - question: "Which is better for security-sensitive codebases?"
     answer: "Superset. Code never leaves your machine. ..."
-  - question: "Is Superset open source?"
-    answer: "Yes. Superset is open source under Apache 2.0 with zero telemetry. Devin is closed source from Cognition."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
faq:
- question: "Can Devin and Superset work together?"
answer: "They serve different workflows. Devin is a cloud-based autonomous engineer. Superset is a local agent orchestrator. You might use Devin for fully autonomous background tasks and Superset for interactive parallel work where you want more control."
- question: "Is Devin worth the price premium?"
answer: "Devin's $500/seat/month buys full autonomy: assign tasks via Slack, get PRs back. If your workflow benefits from hands-off delegation and you have the budget, it can be valuable. If you prefer direct control and cost efficiency, Superset at $20/seat/month plus API costs delivers more throughput per dollar."
- question: "Which is better for security-sensitive codebases?"
answer: "Superset. Code never leaves your machine. Devin runs code on Cognition's cloud infrastructure. For regulated industries, government work, or sensitive IP, local execution is a hard requirement."
- question: "Is Superset open source?"
answer: "Yes. Superset is open source under Apache 2.0 with zero telemetry. Devin is closed source from Cognition."
faq:
- question: "Can Devin and Superset work together?"
answer: "They serve different workflows. Devin is a cloud-based autonomous engineer. Superset is a local agent orchestrator. You might use Devin for fully autonomous background tasks and Superset for interactive parallel work where you want more control."
- question: "Is Devin worth the price premium?"
answer: "Devin's $500/seat/month buys full autonomy: assign tasks via Slack, get PRs back. If your workflow benefits from hands-off delegation and you have the budget, it can be valuable. If you prefer direct control and cost efficiency, Superset at $20/seat/month plus API costs delivers more throughput per dollar."
- question: "Is Superset open source?"
answer: "Yes. Superset is open source under Apache 2.0 with zero telemetry. Devin is closed source from Cognition."
- question: "Which is better for security-sensitive codebases?"
answer: "Superset. Code never leaves your machine. Devin runs code on Cognition's cloud infrastructure. For regulated industries, government work, or sensitive IP, local execution is a hard requirement."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/content/compare/superset-vs-devin.mdx` around lines 18 - 26,
Reorder the frontmatter "faq" array so its question sequence matches the visible
body FAQ order: move the "Is Superset open source?" item to come before "Which
is better for security-sensitive codebases?" (i.e., ensure the questions "Is
Superset open source?" and "Which is better for security-sensitive codebases?"
appear in the same order in the frontmatter `faq` array as they do in the
rendered body); update the `faq` array in the file so the question strings
exactly match the body copy to avoid structured-data mismatches.

competitors: data.competitors ?? [],
keywords: data.keywords ?? [],
image: data.image,
faq: data.faq,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Validate faq frontmatter before assigning it to ComparisonPage.

On Line 34, data.faq is passed through unvalidated. A malformed frontmatter value can break compare page rendering when FAQ JSON-LD is generated.

🛠️ Proposed fix
 		const lastUpdated = normalizeContentDate(data.lastUpdated, {
 			fallbackToNow: false,
 		});
+		const faq =
+			Array.isArray(data.faq)
+				? data.faq
+						.map((item) => {
+							if (
+								typeof item === "object" &&
+								item !== null &&
+								"question" in item &&
+								"answer" in item
+							) {
+								const question = (item as { question?: unknown }).question;
+								const answer = (item as { answer?: unknown }).answer;
+								if (typeof question === "string" && typeof answer === "string") {
+									return { question, answer };
+								}
+							}
+							return null;
+						})
+						.filter(
+							(item): item is { question: string; answer: string } => item !== null,
+						)
+				: undefined;

 		return {
 			slug,
 			url: `/compare/${slug}`,
@@
 			competitors: data.competitors ?? [],
 			keywords: data.keywords ?? [],
 			image: data.image,
-			faq: data.faq,
+			faq: faq && faq.length > 0 ? faq : undefined,
 			content,
 		};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
faq: data.faq,
const lastUpdated = normalizeContentDate(data.lastUpdated, {
fallbackToNow: false,
});
const faq =
Array.isArray(data.faq)
? data.faq
.map((item) => {
if (
typeof item === "object" &&
item !== null &&
"question" in item &&
"answer" in item
) {
const question = (item as { question?: unknown }).question;
const answer = (item as { answer?: unknown }).answer;
if (typeof question === "string" && typeof answer === "string") {
return { question, answer };
}
}
return null;
})
.filter(
(item): item is { question: string; answer: string } => item !== null,
)
: undefined;
return {
slug,
url: `/compare/${slug}`,
competitors: data.competitors ?? [],
keywords: data.keywords ?? [],
image: data.image,
faq: faq && faq.length > 0 ? faq : undefined,
content,
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/marketing/src/lib/compare.ts` at line 34, Validate the frontmatter value
`data.faq` before assigning it to the `ComparisonPage` object: implement a small
validation check (e.g., a `validateFaqFrontmatter` helper or a Zod schema) that
ensures `data.faq` is the expected type (array of Q/A objects or a properly
shaped object with required fields like `question` and `answer`), and only set
`faq: data.faq` when the validation passes; otherwise set `faq` to undefined or
an empty array to avoid rendering/JSON-LD errors. Ensure you call this validator
where `faq: data.faq` is assigned in compare.ts and use the validated value for
the `ComparisonPage` payload.

@github-actions
Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) View Branch
Fly.io Electric (Fly.io) View App
Vercel API (Vercel) Open Preview
Vercel Web (Vercel) Open Preview
Vercel Marketing (Vercel) Open Preview
Vercel Admin (Vercel) Open Preview
Vercel Docs (Vercel) Open Preview

Preview updates automatically with new commits

@AviPeltz AviPeltz closed this May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant