feat(comparison): add Sim vs Competitor comparison pages#5383
Conversation
PR SummaryLow Risk Overview Each detail page renders a sourced fact table (via shared Reviewed by Cursor Bugbot for commit 98131d2. Configure here. |
- New /comparison hub + /comparison/[provider] detail pages for Sim vs 16 competitors (n8n, Zapier, Make, Gumloop, Workato, Retool, Pipedream, OpenAI AgentKit, Tines, StackAI, Power Automate, Vellum, Claude Cowork, Langflow, Flowise), each with ~60 sourced, dated facts across platform, AI capabilities, integrations, pricing, security, observability, and support - Data layer at lib/compare/data (types, per-competitor profiles) is UI-free and independently auditable - BreadcrumbList, ItemList, and FAQPage JSON-LD per page; sitemap picks up all pages automatically via ALL_COMPETITORS - Two new fact categories (parallel execution, Agent2Agent protocol) researched and sourced against every competitor's own docs
Greptile SummaryThis PR adds a
Confidence Score: 5/5Safe to merge — all 16 pages are statically generated, the data layer is UI-free and fully typed, and all issues from prior review rounds are addressed. The change is purely additive (new routes, new data files, one sitemap update, one footer link). The type system enforces fact-key correctness at build time via No files require special attention — the data files are large but uniform in structure, and the rendering components are small and focused. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["/comparison (hub page)"] -->|lists| B["ALL_COMPETITORS array (utils.ts)"]
B -->|generates static params| C["/comparison/[provider] (detail page)"]
D["lib/compare/data/types.ts\nComparisonFacts, CompetitorProfile"] --> E["lib/compare/data/sim.ts\nsimProfile"]
D --> F["lib/compare/data/competitors/*.ts\n15 competitor profiles"]
E --> G["lib/compare/data/index.ts\n(barrel)"]
F --> G
G --> H["utils.ts\nALL_COMPETITORS, buildFAQs, buildBottomLine"]
H --> A
H --> C
I["comparison-sections.ts\nCOMPARISON_SECTIONS, defineSection"] --> J["ComparisonTable (server)"]
I --> K["factsToProperties → JSON-LD ItemList"]
E --> J
F --> J
J --> L["FactValue (server)"]
L --> M["SourceLink ('use client')\nTooltip + anchor"]
C --> N["BreadcrumbList JSON-LD"]
C --> K
C --> O["FAQPage JSON-LD\nbuildComparisonFaqs"]
C --> P["LandingFAQ UI"]
H --> Q["sitemap.ts\ncomparisonPages"]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A["/comparison (hub page)"] -->|lists| B["ALL_COMPETITORS array (utils.ts)"]
B -->|generates static params| C["/comparison/[provider] (detail page)"]
D["lib/compare/data/types.ts\nComparisonFacts, CompetitorProfile"] --> E["lib/compare/data/sim.ts\nsimProfile"]
D --> F["lib/compare/data/competitors/*.ts\n15 competitor profiles"]
E --> G["lib/compare/data/index.ts\n(barrel)"]
F --> G
G --> H["utils.ts\nALL_COMPETITORS, buildFAQs, buildBottomLine"]
H --> A
H --> C
I["comparison-sections.ts\nCOMPARISON_SECTIONS, defineSection"] --> J["ComparisonTable (server)"]
I --> K["factsToProperties → JSON-LD ItemList"]
E --> J
F --> J
J --> L["FactValue (server)"]
L --> M["SourceLink ('use client')\nTooltip + anchor"]
C --> N["BreadcrumbList JSON-LD"]
C --> K
C --> O["FAQPage JSON-LD\nbuildComparisonFaqs"]
C --> P["LandingFAQ UI"]
H --> Q["sitemap.ts\ncomparisonPages"]
Reviews (6): Last reviewed commit: "fix(comparison): strip Yes/No prefix bef..." | Re-trigger Greptile |
eb41f1c to
e3b72eb
Compare
…ct copy - Remove promotional/superlative adjectives applied to competitors (Zapier "one of the largest catalogs", Workato "notably wide", Retool "seamless"/"trusted solution", OpenAI "cutting-edge", Flowise "deep"/"mature"/"most widely adopted", Make "robust") - Reword the few places Sim's own accurate limitations read as unflattering rather than neutral fact (dynamic tool use, model fallback, durability, async execution, support channels, tracing) without changing the underlying facts - Restore the "Yes:"/"No:" value prefix on two Sim facts where it was accidentally dropped during rewording, since FactValue depends on that prefix to render the check/X status icon
- Fix parseFactValue regex to require a word boundary after Yes/No, so values like "Not documented"/"Not publicly documented" no longer get misread as a boolean "No" and render as neutral text again (Cursor) - Reword the self-hosting FAQ question to drop the false presupposition that the competitor doesn't self-host, which was wrong for n8n, Langflow, and Flowise (Greptile) - Rename isLastRow -> isNotLastRow in comparison-table.tsx to match what the variable actually computes (Greptile) - Move critters to devDependencies; it's a next build -time-only CSS inliner, not needed at runtime (Greptile) - Sitemap lastModified for comparison pages now matches the max(Sim, competitor) verified-date logic each page's own JSON-LD dateModified already uses, so the two never disagree (Cursor)
|
@cursor review |
- Two hub FAQ answers prepended "Yes." to fact values that already start with "Yes:", producing "Yes. Yes: ..." in visible copy and FAQPage JSON-LD. Export and reuse ensurePeriod instead of a hardcoded prefix. - The integrations-count FAQ answer ran two sentences together with no period before "Combined with...". Fixed with the same ensurePeriod helper.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fa00f5e. Configure here.
… section The 5 facts it previewed (self-hosting, environment promotion, human-in-the-loop, pricing model, data residency) are the exact same rows shown again immediately below in the full comparison table, so the section read as pure repetition for a human scrolling past it.
summarizeFact fed the raw fact value through lowercaseFirst even when it started with "Yes: "/"No: ", producing broken mid-sentence FAQ text like "n8n: yes: many providers via dedicated Chat Model nodes." Strip the boolean prefix first, matching Greptile's suggested fix.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 98131d2. Configure here.

Summary
/comparisonhub +/comparison/[provider]detail pages: Sim vs 16 competitors (n8n, Zapier, Make, Gumloop, Workato, Retool, Pipedream, OpenAI AgentKit, Tines, StackAI, Power Automate, Vellum, Claude Cowork, Langflow, Flowise)lib/compare/datais UI-free and independently auditable; adding a new fact or competitor requires no page-template changesadditionalProperty), and FAQPage JSON-LD on every page; sitemap picks up all pages automaticallyType of Change
Testing
tsc --noEmit,biome check, andbun run check:api-validationall pass cleannext build) completes with zero errors across all 737 pagesChecklist