web: agent landing pages, /agents hub, and JSON-LD across content pages - #6683
Conversation
… pages Add per-agent landing pages for Gemini CLI, Aider, Amp, and Cursor CLI, plus an /agents hub that links every agent page. Each mirrors the existing claude-code-terminal pattern (workspaces, notification rings, iOS, scriptable). Add reusable JSON-LD helpers (json-ld.tsx) and render: - FAQPage + BreadcrumbList on all agent landing pages (3 existing + 4 new + hub) - Article + BreadcrumbList on all blog posts - BreadcrumbList on all docs pages Register new paths in sitemap.ts and add landing.links entries. English content only in this commit; other locales follow.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds five new localized agent landing pages under ChangesAgent Landing Pages, JSON-LD Schema, and i18n Expansion
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 24 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (24 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Fixes web-typecheck (bun test) failure: agent-page-variants.test asserts every sitemap page resolves to a Markdown/text variant. Adds /agents, /gemini-cli, /aider, /amp, /cursor-cli to agentReadablePages so they also appear in llms.txt.
Greptile SummaryThis PR fills an SEO gap by adding a
Confidence Score: 5/5Web-only marketing and SEO change with no app or runtime impact; all registries are in sync and redirects correctly cover old paths. All registry entries (sitemap, agentReadablePages, guides ARTICLES, landing.links) are kept in sync for every new page. The previously-flagged FAQ rendering bug is correctly fixed using t.rich() in LandingFaq and t.raw()+stripTags() in LandingSchema. The km.json missing keys are addressed. Redirects cover all three moved slugs with .md/.txt variants and locale prefixes. No logic errors or missing registrations were found. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["/claude-code-terminal"] -->|301 redirect| C
A2["/codex-cli"] -->|301 redirect| D
A3["/opencode"] -->|301 redirect| E
B["/agents hub"]
B --> C["/agents/claude-code"]
B --> D["/agents/codex"]
B --> E["/agents/opencode"]
B --> F["/agents/gemini-cli NEW"]
B --> G["/agents/aider NEW"]
B --> H["/agents/amp NEW"]
B --> I["/agents/cursor-cli NEW"]
C & D & E & F & G & H & I --> N[LandingSchema FAQPage + BreadcrumbList]
J[Blog pages] --> O[BlogSchema Article + BreadcrumbList]
K[Docs pages] --> P[DocsSchema BreadcrumbList]
N & O & P --> Q[json-ld.tsx helper]
%%{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["/claude-code-terminal"] -->|301 redirect| C
A2["/codex-cli"] -->|301 redirect| D
A3["/opencode"] -->|301 redirect| E
B["/agents hub"]
B --> C["/agents/claude-code"]
B --> D["/agents/codex"]
B --> E["/agents/opencode"]
B --> F["/agents/gemini-cli NEW"]
B --> G["/agents/aider NEW"]
B --> H["/agents/amp NEW"]
B --> I["/agents/cursor-cli NEW"]
C & D & E & F & G & H & I --> N[LandingSchema FAQPage + BreadcrumbList]
J[Blog pages] --> O[BlogSchema Article + BreadcrumbList]
K[Docs pages] --> P[DocsSchema BreadcrumbList]
N & O & P --> Q[json-ld.tsx helper]
Reviews (4): Last reviewed commit: "web: use raw FAQ strings in landing JSON..." | Re-trigger Greptile |
| @@ -1718,7 +1718,127 @@ | |||
| "ohMyCodex": "oh-my-codex", | |||
There was a problem hiding this comment.
Missing FAQ keys in Khmer locale
The Khmer (km.json) catalog is the only locale that didn't receive the new FAQ keys for the three existing agent landing pages. landing.claude, landing.codex, and landing.opencode are each missing faqTitle, faqQ1–faqQ4, and faqA1–faqA4 (27 keys total). Additionally, landing.links.home is absent from km.json while it is present in all 19 other locales.
At runtime, next-intl will either throw or silently fall back to the key name for Khmer visitors on /km/claude-code-terminal, /km/codex-cli, /km/opencode, and every page that renders a Home > breadcrumb (docs, blog, and all agent landings). The PR description says "every new key present in every catalog, no English fallback" but that's not the case for km.json.
Rule Used: Flag production user-facing text that is not fully... (source)
| export function LandingFaq({ namespace }: { namespace: string }) { | ||
| const t = useTranslations(namespace); | ||
| return ( | ||
| <> | ||
| <h2>{t("faqTitle")}</h2> | ||
| {[1, 2, 3, 4].map((n) => ( | ||
| <div key={n}> | ||
| <p> | ||
| <strong>{t(`faqQ${n}`)}</strong> | ||
| </p> | ||
| <p>{t(`faqA${n}`)}</p> | ||
| </div> | ||
| ))} | ||
| </> | ||
| ); | ||
| } |
There was a problem hiding this comment.
FAQ answers with HTML tags rendered as literal text
LandingFaq renders answer strings with a plain {t('faqA1')} call, but every agent namespace's faqA1 value contains an HTML <code>...</code> tag (e.g. "so <code>claude</code> runs in any workspace"). next-intl's t() returns the raw string; React then auto-escapes it, so users will see the literal characters <code>claude</code> in the FAQ section instead of a styled code element.
The intro paragraphs on the same pages correctly use t.rich("intro", { code }) to process the same tag pattern. The FAQ answers need the same treatment, or the <code> tags need to be removed from the message values.
| export function LandingFaq({ namespace }: { namespace: string }) { | |
| const t = useTranslations(namespace); | |
| return ( | |
| <> | |
| <h2>{t("faqTitle")}</h2> | |
| {[1, 2, 3, 4].map((n) => ( | |
| <div key={n}> | |
| <p> | |
| <strong>{t(`faqQ${n}`)}</strong> | |
| </p> | |
| <p>{t(`faqA${n}`)}</p> | |
| </div> | |
| ))} | |
| </> | |
| ); | |
| } | |
| /** Renders the localized FAQ section body for an agent landing page. */ | |
| export function LandingFaq({ namespace }: { namespace: string }) { | |
| const t = useTranslations(namespace); | |
| const code = (chunks: React.ReactNode) => <code>{chunks}</code>; | |
| return ( | |
| <> | |
| <h2>{t("faqTitle")}</h2> | |
| {[1, 2, 3, 4].map((n) => ( | |
| <div key={n}> | |
| <p> | |
| <strong>{t.rich(`faqQ${n}`, { code })}</strong> | |
| </p> | |
| <p>{t.rich(`faqA${n}`, { code })}</p> | |
| </div> | |
| ))} | |
| </> | |
| ); | |
| } |
LandingFaq now uses the homepage FAQ treatment (muted section heading, medium-weight question, muted answer, space-y-5) and renders answers with t.rich so inline <code> tokens (e.g. gemini, aider) display as code instead of literal tag text. Shared across all agent landing pages.
New (landing) pages must be registered in sitemap.ts, agentReadablePages (agent-page-paths.ts), the /guides ARTICLES list, and landing.links. Wired into CodeRabbit (path instructions + blocking check) and Greptile (config rule + files entry + rules.md). Codifies the gap that left the new agent pages out of agentReadablePages and /guides in this PR.
Move the seven agent landing pages under the /agents hub:
- /claude-code-terminal -> /agents/claude-code
- /codex-cli -> /agents/codex
- /opencode -> /agents/opencode
- new: /agents/{gemini-cli,aider,amp,cursor-cli}
Permanent redirects (bare + all locale prefixes) keep the three previously
shipped slugs working. Updates sitemap, agentReadablePages (md/txt + llms.txt),
the /guides index, breadcrumb schema, and all internal cross-links. Breadcrumbs
now read Home > Agents > <agent> matching the URL structure.
LandingSchema/DocsSchema/BlogSchema read landing.links.home, and the moved claude/codex/opencode pages render LandingFaq, but km.json was missing links.home and faqTitle/faqQ1-4/faqA1-4 for claude/codex/opencode. That threw missing-message errors on every /km docs, blog, and agents page. Adds the Khmer translations. Caught by autoreview.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit fda825d. Configure here.
The slug move only redirected HTML paths; old agent-readable variants (/codex-cli.md, /opencode.txt, /claude-code-terminal.md, locale-prefixed) 404'd. They were live and advertised in llms.txt, so redirect .md/.txt to the new /agents/<agent> variants too. Caught by autoreview.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web/next.config.ts`:
- Around line 14-15: The localePrefix variable at line 15 contains a hardcoded
list of locales as a string pattern, which duplicates locale ownership and can
get out of sync when new locales are added. Instead of maintaining this
hardcoded matcher, import the locale registry from the shared source, filter out
the default locale (en), and dynamically build the localePrefix pattern by
joining the remaining locales with pipe separators. This ensures the redirect
locale matcher automatically stays in sync with any locale additions made to the
central registry.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3c10530a-5dd0-4515-bedc-1f323096cac6
📒 Files selected for processing (80)
.coderabbit.yaml.github/review-bot-rules/README.md.github/review-bot-rules/landing-page-registry-parity.md.greptile/config.json.greptile/files.json.greptile/rules.mdweb/app/[locale]/(landing)/agents/aider/page.tsxweb/app/[locale]/(landing)/agents/amp/page.tsxweb/app/[locale]/(landing)/agents/claude-code/page.tsxweb/app/[locale]/(landing)/agents/codex/page.tsxweb/app/[locale]/(landing)/agents/cursor-cli/page.tsxweb/app/[locale]/(landing)/agents/gemini-cli/page.tsxweb/app/[locale]/(landing)/agents/opencode/page.tsxweb/app/[locale]/(landing)/agents/page.tsxweb/app/[locale]/(landing)/best-terminal-for-mac/page.tsxweb/app/[locale]/(landing)/guides/page.tsxweb/app/[locale]/(landing)/landing-schema.tsxweb/app/[locale]/blog/blog-schema.tsxweb/app/[locale]/blog/cmd-shift-u/page.tsxweb/app/[locale]/blog/cmux-claude-teams/page.tsxweb/app/[locale]/blog/cmux-finder/page.tsxweb/app/[locale]/blog/cmux-history/page.tsxweb/app/[locale]/blog/cmux-omo/page.tsxweb/app/[locale]/blog/cmux-ssh/page.tsxweb/app/[locale]/blog/cmux-vault/page.tsxweb/app/[locale]/blog/gpl/page.tsxweb/app/[locale]/blog/introducing-cmux/page.tsxweb/app/[locale]/blog/markdown-viewer/page.tsxweb/app/[locale]/blog/passkey-auth/page.tsxweb/app/[locale]/blog/session-restore/page.tsxweb/app/[locale]/blog/show-hn-launch/page.tsxweb/app/[locale]/blog/task-manager/page.tsxweb/app/[locale]/blog/unread-shortcuts/page.tsxweb/app/[locale]/blog/zen-of-cmux/page.tsxweb/app/[locale]/components/json-ld.tsxweb/app/[locale]/docs/agent-integrations/claude-code-teams/page.tsxweb/app/[locale]/docs/agent-integrations/oh-my-claudecode/page.tsxweb/app/[locale]/docs/agent-integrations/oh-my-codex/page.tsxweb/app/[locale]/docs/agent-integrations/oh-my-opencode/page.tsxweb/app/[locale]/docs/api/page.tsxweb/app/[locale]/docs/browser-automation/page.tsxweb/app/[locale]/docs/changelog/page.tsxweb/app/[locale]/docs/concepts/page.tsxweb/app/[locale]/docs/configuration/page.tsxweb/app/[locale]/docs/custom-commands/page.tsxweb/app/[locale]/docs/dock/page.tsxweb/app/[locale]/docs/docs-schema.tsxweb/app/[locale]/docs/getting-started/page.tsxweb/app/[locale]/docs/ios/page.tsxweb/app/[locale]/docs/keyboard-shortcuts/page.tsxweb/app/[locale]/docs/notifications/page.tsxweb/app/[locale]/docs/remote-tmux/page.tsxweb/app/[locale]/docs/session-restore/page.tsxweb/app/[locale]/docs/skills/page.tsxweb/app/[locale]/docs/ssh/page.tsxweb/app/[locale]/docs/textbox/page.tsxweb/app/[locale]/docs/workspace-groups/page.tsxweb/app/lib/agent-page-paths.tsweb/app/sitemap.tsweb/messages/ar.jsonweb/messages/bs.jsonweb/messages/da.jsonweb/messages/de.jsonweb/messages/en.jsonweb/messages/es.jsonweb/messages/fr.jsonweb/messages/it.jsonweb/messages/ja.jsonweb/messages/km.jsonweb/messages/ko.jsonweb/messages/no.jsonweb/messages/pl.jsonweb/messages/pt-BR.jsonweb/messages/ru.jsonweb/messages/th.jsonweb/messages/tr.jsonweb/messages/uk.jsonweb/messages/zh-CN.jsonweb/messages/zh-TW.jsonweb/next.config.ts
| const localePrefix = | ||
| ":locale(ja|zh-CN|zh-TW|ko|de|es|fr|it|da|pl|ru|bs|ar|no|pt-BR|th|tr|km|uk)"; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Derive redirect locales from the shared locale registry.
At Line 15, the locale matcher is hardcoded in next.config.ts. This duplicates locale ownership and can silently miss redirects for newly added locales. Build this matcher from the existing locale source (excluding en) so redirects stay in sync automatically. As per path instructions, “keep the locale/message registry aligned.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/next.config.ts` around lines 14 - 15, The localePrefix variable at line
15 contains a hardcoded list of locales as a string pattern, which duplicates
locale ownership and can get out of sync when new locales are added. Instead of
maintaining this hardcoded matcher, import the locale registry from the shared
source, filter out the default locale (en), and dynamically build the
localePrefix pattern by joining the remaining locales with pipe separators. This
ensures the redirect locale matcher automatically stays in sync with any locale
additions made to the central registry.
Source: Path instructions
The agent-readable variant router canonicalizes /en/... paths and dotted variants bypass the locale middleware, so /en/codex-cli.md etc. must redirect too. Adds explicit /en rules (to the canonical unprefixed new path). Caught by autoreview.
…wers) LandingSchema built FAQ answers with t(), but answers contain <code> markup plus ICU-significant chars (e.g. French apostrophes). next-intl then failed to format and emitted the message key (landing.<ns>.faqA1) into the structured data instead of the answer. Use t.raw() + stripTags like the homepage FAQ schema. Caught by autoreview.

Competitive SEO gap-fill vs warp.dev. Two changes, both web-only.
#4 Per-agent landing pages + hub
New localized landing pages mirroring the existing
/claude-code-terminalpattern:/agents— hub introducing cmux as the terminal for coding agents, links all seven/gemini-cli,/aider,/amp,/cursor-cliEach covers how cmux helps run that agent (parallel workspaces, notification rings, vertical tabs, iOS companion, scriptable socket). Registered in
sitemap.ts; cross-linked vialanding.links.#5 Structured data on content pages
Previously only
SoftwareApplication(global) +FAQPage(homepage). Added a reusable JSON-LD helper and applied:FAQPage+BreadcrumbListon every agent landing pageArticle+BreadcrumbListon every blog postBreadcrumbListon every docs pageLocalization
All new copy (5 namespaces + FAQ + cross-links) translated into all 20 locales. Audit: every new key present in every catalog, no English fallback.
tsc clean. Web-only, no app/runtime changes.
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Note
Low Risk
Marketing-site and i18n-only changes with no app runtime or auth impact; main risk is broken old URLs or registry drift if redirects or sitemap/agent paths are incomplete.
Overview
Adds a coding-agents SEO hub at
/agentsplus per-agent pages (Gemini CLI, Aider, Amp, Cursor CLI) and moves Claude Code, Codex, and OpenCode from top-level slugs to/agents/*, with matching updates to sitemap,agentReadablePages,/guidesARTICLES, andlanding.linkscross-links.Introduces shared
json-ldhelpers and wires FAQ + breadcrumb JSON-LD on agent landings (LandingSchema/LandingFaq), Article + breadcrumbs on blog posts (BlogSchema), and breadcrumbs on docs (DocsSchema). Existing agent pages gain FAQ sections and updated related links.Adds a landing-page registry parity review rule (CodeRabbit, Greptile, pre-merge check) so new
(landing)routes must stay in sync across sitemap, agent-readable paths, guides index, and nav copy. Full locale catalogs gain newlanding.*namespaces, FAQ strings, and link labels for the new pages.Reviewed by Cursor Bugbot for commit 5f10591. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Add agent landing pages under
/agentswith a new hub and shared FAQ UI. Add JSON‑LD across agents, blog, and docs, and redirect old HTML and.md/.txtslugs.New Features
/agentshub and/agents/{claude-code,codex,opencode,gemini-cli,aider,amp,cursor-cli}with breadcrumbs Home > Agents > .landing.links; sitemap and/guidesupdated.<code>rendering.Bug Fixes
/agentsand all/agents/*pages inagentReadablePagesso.md/.txtvariants andllms.txtwork; tests pass./claude-code-terminal,/codex-cli,/opencodeto new/agents/*paths, including their.md/.txtvariants and explicit/en‑prefixed routes.(landing)pages missing entries insitemap.ts,agentReadablePages,/guidesARTICLES, orlanding.links./kmruntime crash by adding missing Khmerlanding.links.homeand agent FAQ keys.<code>markup and ICU chars), so localized answers render correctly.Written for commit 5f10591. Summary will update on new commits.
Summary by CodeRabbit
New Features
Refactor
/agents/*path structure with permanent redirects from old locationsChores