Repository navigation
Fix residual docs metadata from Ahrefs audit - #7893
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe PR centralizes metadata generation for audited documentation pages, adds localized SEO copy selection and validation, updates translated metadata strings, and expands SEO regression tests across routes and locales. ChangesAudited docs SEO
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (2 errors, 1 warning)
✅ Passed checks (22 passed)
✨ 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 |
Greptile SummaryThis PR centralizes audited metadata for 17 documentation route families. The main changes are:
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (19): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile |
7f9c968 to
29dd57e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 29dd57e68a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
29dd57e to
951ec39
Compare
8c9184b to
7671030
Compare
# Conflicts: # web/i18n/audited-seo.ts # web/i18n/seo.ts # web/tests/seo.test.ts
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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/messages/de.json`:
- Line 1469: Update the German metaDescriptionShort translation to remove the
duplicated “mit” by using grammatically correct phrasing such as “per cmux ssh
mit Remote-Computern,” while preserving the rest of the description unchanged.
- Around line 1539-1541: Update the German `metaDescriptionShort` value in the
affected translation entry so it is genuinely condensed and no longer
byte-identical to `metaDescription`, while preserving the same core meaning and
language.
In `@web/messages/it.json`:
- Around line 1539-1540: Update the ohMyOpenCode metaDescriptionShort
translation in it.json so it is a genuinely condensed version rather than a
verbatim duplicate of metaDescription, matching the shorter-copy intent used by
the corresponding es.json, fr.json, and bs.json entries.
In `@web/messages/uk.json`:
- Line 1554: Align the metaDescriptionShort entries in the touched Ukrainian and
Simplified Chinese locale files so the same audited pages are covered in each,
including keyboardShortcuts, ohMyOpenCode, ssh, and ios. Add the missing curated
descriptions or remove inconsistent entries as needed, preserving the existing
localized wording and ensuring identical page coverage across both locale files.
In `@web/messages/zh-CN.json`:
- Around line 1540-1541: Update the ohMyOpenCode entry’s metaDescriptionShort to
a genuinely shorter, distinct summary rather than duplicating metaDescription,
while preserving metaDescription unchanged and keeping the short description’s
core product and cmux context.
- Line 1072: Align metaDescriptionShort coverage across zh-CN.json and uk.json
for the audited message entries: add the missing descriptions for ssh and ios in
zh-CN, and for keyboardShortcuts and ohMyOpenCode in uk, including the
additional entry at the referenced location. Preserve the existing
locale-specific wording and JSON structure.
🪄 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: 5f04cf62-cd6c-4244-86c1-4f5b0bf72a35
📒 Files selected for processing (36)
web/app/[locale]/(landing)/docs/agent-integrations/oh-my-opencode/page.tsxweb/app/[locale]/(landing)/docs/api/page.tsxweb/app/[locale]/(landing)/docs/audited-docs-metadata.tsweb/app/[locale]/(landing)/docs/browser-automation/page.tsxweb/app/[locale]/(landing)/docs/concepts/page.tsxweb/app/[locale]/(landing)/docs/configuration/page.tsxweb/app/[locale]/(landing)/docs/custom-commands/page.tsxweb/app/[locale]/(landing)/docs/dock/page.tsxweb/app/[locale]/(landing)/docs/getting-started/page.tsxweb/app/[locale]/(landing)/docs/ios/page.tsxweb/app/[locale]/(landing)/docs/keyboard-shortcuts/page.tsxweb/app/[locale]/(landing)/docs/notifications/page.tsxweb/app/[locale]/(landing)/docs/remote-tmux/page.tsxweb/app/[locale]/(landing)/docs/session-restore/page.tsxweb/app/[locale]/(landing)/docs/skills/page.tsxweb/app/[locale]/(landing)/docs/ssh/page.tsxweb/app/[locale]/(landing)/docs/textbox/page.tsxweb/app/[locale]/(landing)/docs/workspace-groups/page.tsxweb/i18n/audited-seo.tsweb/i18n/seo.tsweb/messages/bs.jsonweb/messages/de.jsonweb/messages/es.jsonweb/messages/fr.jsonweb/messages/it.jsonweb/messages/ja.jsonweb/messages/km.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/tests/seo.test.ts
| "title": "SSH", | ||
| "metaTitle": "SSH", | ||
| "metaDescription": "Stellen Sie mit cmux ssh eine Verbindung zu Remote-Computern her. Browserfenster werden durch das Remote-Netzwerk geleitet, Bilder werden per Drag-and-Drop per SCP verschoben und Agentenbenachrichtigungen kommen sofort nach Hause.", | ||
| "metaDescriptionShort": "Verbinde dich mit cmux ssh mit Remote-Computern. Browser laufen über das Remote-Netzwerk, Dateien über scp und Agentenmeldungen zurück zum Mac.", |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Grammar: duplicated "mit" in German short description.
"Verbinde dich mit cmux ssh mit Remote-Computern." repeats "mit", which reads as a translation slip (e.g. "Verbinde dich per cmux ssh mit Remote-Computern." would be correct German).
✏️ Proposed fix
- "metaDescriptionShort": "Verbinde dich mit cmux ssh mit Remote-Computern. Browser laufen über das Remote-Netzwerk, Dateien über scp und Agentenmeldungen zurück zum Mac.",
+ "metaDescriptionShort": "Verbinde dich per cmux ssh mit Remote-Computern. Browser laufen über das Remote-Netzwerk, Dateien über scp und Agentenmeldungen zurück zum Mac.",📝 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.
| "metaDescriptionShort": "Verbinde dich mit cmux ssh mit Remote-Computern. Browser laufen über das Remote-Netzwerk, Dateien über scp und Agentenmeldungen zurück zum Mac.", | |
| "metaDescriptionShort": "Verbinde dich per cmux ssh mit Remote-Computern. Browser laufen über das Remote-Netzwerk, Dateien über scp und Agentenmeldungen zurück zum Mac.", |
🤖 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/messages/de.json` at line 1469, Update the German metaDescriptionShort
translation to remove the duplicated “mit” by using grammatically correct
phrasing such as “per cmux ssh mit Remote-Computern,” while preserving the rest
of the description unchanged.
| "metaDescription": "cmux omo startet OpenCode mit oh-my-openagent. Claude, GPT, Gemini und Grok arbeiten parallel als Agenten, jeweils in einem nativen cmux-Split.", | ||
| "metaDescriptionShort": "cmux omo startet OpenCode mit oh-my-openagent. Claude, GPT, Gemini und Grok arbeiten parallel als Agenten, jeweils in einem nativen cmux-Split." | ||
| }, |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
metaDescriptionShort is an exact duplicate of metaDescription.
Unlike the equivalent ohMyOpenCode keys in es.json, fr.json, and bs.json (where the short variant is genuinely condensed), this German pair is byte-identical. This defeats the purpose of a distinct "short" social/meta description and re-introduces the duplicated-content pattern this PR is meant to eliminate.
✏️ Suggested distinct short copy
"metaDescription": "cmux omo startet OpenCode mit oh-my-openagent. Claude, GPT, Gemini und Grok arbeiten parallel als Agenten, jeweils in einem nativen cmux-Split.",
- "metaDescriptionShort": "cmux omo startet OpenCode mit oh-my-openagent. Claude, GPT, Gemini und Grok arbeiten parallel als Agenten, jeweils in einem nativen cmux-Split."
+ "metaDescriptionShort": "cmux omo koordiniert Claude, GPT, Gemini und Grok als parallele OpenCode-Agenten, jeweils in einem nativen cmux-Split."📝 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.
| "metaDescription": "cmux omo startet OpenCode mit oh-my-openagent. Claude, GPT, Gemini und Grok arbeiten parallel als Agenten, jeweils in einem nativen cmux-Split.", | |
| "metaDescriptionShort": "cmux omo startet OpenCode mit oh-my-openagent. Claude, GPT, Gemini und Grok arbeiten parallel als Agenten, jeweils in einem nativen cmux-Split." | |
| }, | |
| "metaDescription": "cmux omo startet OpenCode mit oh-my-openagent. Claude, GPT, Gemini und Grok arbeiten parallel als Agenten, jeweils in einem nativen cmux-Split.", | |
| "metaDescriptionShort": "cmux omo koordiniert Claude, GPT, Gemini und Grok als parallele OpenCode-Agenten, jeweils in einem nativen cmux-Split." | |
| }, |
🤖 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/messages/de.json` around lines 1539 - 1541, Update the German
`metaDescriptionShort` value in the affected translation entry so it is
genuinely condensed and no longer byte-identical to `metaDescription`, while
preserving the same core meaning and language.
| "metaDescription": "cmux omo avvia OpenCode con il plugin oh-my-openagent. Claude, GPT, Gemini e Grok lavorano in parallelo come agenti, ciascuno in una divisione cmux nativa.", | ||
| "metaDescriptionShort": "cmux omo avvia OpenCode con il plugin oh-my-openagent. Claude, GPT, Gemini e Grok lavorano in parallelo come agenti, ciascuno in una divisione cmux nativa." |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
metaDescriptionShort duplicates metaDescription verbatim.
Same issue as de.json: the short variant for ohMyOpenCode is byte-identical to the full description, unlike the genuinely condensed short copy used for this key in es.json/fr.json/bs.json.
✏️ Suggested distinct short copy
"metaDescription": "cmux omo avvia OpenCode con il plugin oh-my-openagent. Claude, GPT, Gemini e Grok lavorano in parallelo come agenti, ciascuno in una divisione cmux nativa.",
- "metaDescriptionShort": "cmux omo avvia OpenCode con il plugin oh-my-openagent. Claude, GPT, Gemini e Grok lavorano in parallelo come agenti, ciascuno in una divisione cmux nativa."
+ "metaDescriptionShort": "cmux omo coordina Claude, GPT, Gemini e Grok come agenti OpenCode paralleli, ciascuno in una divisione cmux nativa."📝 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.
| "metaDescription": "cmux omo avvia OpenCode con il plugin oh-my-openagent. Claude, GPT, Gemini e Grok lavorano in parallelo come agenti, ciascuno in una divisione cmux nativa.", | |
| "metaDescriptionShort": "cmux omo avvia OpenCode con il plugin oh-my-openagent. Claude, GPT, Gemini e Grok lavorano in parallelo come agenti, ciascuno in una divisione cmux nativa." | |
| "metaDescription": "cmux omo avvia OpenCode con il plugin oh-my-openagent. Claude, GPT, Gemini e Grok lavorano in parallelo come agenti, ciascuno in una divisione cmux nativa.", | |
| "metaDescriptionShort": "cmux omo coordina Claude, GPT, Gemini e Grok come agenti OpenCode paralleli, ciascuno in una divisione cmux nativa." |
🤖 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/messages/it.json` around lines 1539 - 1540, Update the ohMyOpenCode
metaDescriptionShort translation in it.json so it is a genuinely condensed
version rather than a verbatim duplicate of metaDescription, matching the
shorter-copy intent used by the corresponding es.json, fr.json, and bs.json
entries.
| "title": "SSH", | ||
| "metaTitle": "SSH", | ||
| "metaDescription": "Підключайтеся до віддалених машин за допомогою cmux ssh. Панелі браузера маршрутизуються через віддалену мережу, зображення перетягуються через scp, а сповіщення агента надходять додому.", | ||
| "metaDescriptionShort": "Підключайтеся через cmux ssh до віддалених машин, маршрутизуйте браузер віддалено, передавайте файли через scp і отримуйте сповіщення агентів.", |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show supported locales and message files.
sed -n '1,220p' web/i18n/routing.ts
printf '\n--- message files ---\n'
git ls-files 'web/messages/*.json' | sort
printf '\n--- metaDescriptionShort occurrences ---\n'
rg -n '"metaDescriptionShort"\s*:' web/messages/*.jsonRepository: manaflow-ai/cmux
Length of output: 9755
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Compare coverage of metaDescriptionShort for the likely audited docs keys.
python3 - <<'PY'
import json, glob, os
from collections import defaultdict
files = sorted(glob.glob('web/messages/*.json'))
keys = ["ssh", "ios", "keyboardShortcuts", "ohMyOpenCode"]
for path in files:
with open(path, encoding='utf-8') as f:
data = json.load(f)
found = {}
# Search top-level namespaces recursively for those page keys.
for key in keys:
# Most message files have docs metadata nested under docs.*; print any subtree containing the key.
def walk(obj, prefix=""):
if isinstance(obj, dict):
if key in obj and isinstance(obj[key], dict):
if "metaDescriptionShort" in obj[key]:
return obj[key]["metaDescriptionShort"]
for k, v in obj.items():
res = walk(v, prefix + k + ".")
if res is not None:
return res
return None
found[key] = walk(data)
print(os.path.basename(path), found)
PYRepository: manaflow-ai/cmux
Length of output: 5105
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# If the metadata lives under docsMetadata/auditedDocsMetadata, inspect those sections directly.
python3 - <<'PY'
import json, glob, os
for path in sorted(glob.glob('web/messages/*.json')):
with open(path, encoding='utf-8') as f:
data = json.load(f)
def pick(d, path_keys):
for k in path_keys:
if not isinstance(d, dict) or k not in d:
return None
d = d[k]
return d
# Common possible locations; print if present.
candidates = [
("docsMetadata",),
("auditedDocsMetadata",),
("metadata",),
("docs",),
]
print("\n", os.path.basename(path))
for cand in candidates:
node = pick(data, cand)
if isinstance(node, dict):
for k in ("ssh", "ios", "keyboardShortcuts", "ohMyOpenCode"):
if k in node:
val = node[k]
if isinstance(val, dict) and "metaDescriptionShort" in val:
print(" ", ".".join(cand + (k,)), "=>", val["metaDescriptionShort"])
PYRepository: manaflow-ai/cmux
Length of output: 4168
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find where the audited docs metadata is stored in each locale catalog.
rg -n '"(auditedDocsMetadata|docsMetadata|metaDescriptionShort|keyboardShortcuts|ohMyOpenCode|ssh|ios)"' web/messages/*.json | head -n 400Repository: manaflow-ai/cmux
Length of output: 24476
Align curated meta descriptions across locales.
web/messages/uk.json:1554,1625 and web/messages/zh-CN.json:1072,1541 split the audited metaDescriptionShort pages between different locale subsets, so some locales still lack curated descriptions for keyboardShortcuts, ohMyOpenCode, ssh, or ios. Make the page set and metaDescriptionShort coverage identical in every touched locale file.
🤖 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/messages/uk.json` at line 1554, Align the metaDescriptionShort entries in
the touched Ukrainian and Simplified Chinese locale files so the same audited
pages are covered in each, including keyboardShortcuts, ohMyOpenCode, ssh, and
ios. Add the missing curated descriptions or remove inconsistent entries as
needed, preserving the existing localized wording and ensuring identical page
coverage across both locale files.
| "title": "快捷键", | ||
| "description": "cmux 中所有可用的快捷键,按类别分组。", | ||
| "metaDescription": "cmux 的所有 macOS 快捷键,涵盖工作区、surface、分屏面板、浏览器、通知、查找和窗口管理。", | ||
| "metaDescriptionShort": "cmux 的所有 macOS 快捷键,涵盖工作区、surface、分屏面板、浏览器、通知、查找、可配置的键盘操作、搜索流程与窗口导航。", |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Cross-locale metaDescriptionShort coverage gap (mirrors uk.json in reverse).
zh-CN.json adds metaDescriptionShort for keyboardShortcuts, textBox, and ohMyOpenCode, but not for ssh/ios — while web/messages/uk.json does the opposite (adds it for ssh/ios, omits it for keyboardShortcuts/ohMyOpenCode). This same-PR divergence means the curated short description isn't consistently available per locale for the audited page set.
Also applies to: 1526-1526
🤖 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/messages/zh-CN.json` at line 1072, Align metaDescriptionShort coverage
across zh-CN.json and uk.json for the audited message entries: add the missing
descriptions for ssh and ios in zh-CN, and for keyboardShortcuts and
ohMyOpenCode in uk, including the additional entry at the referenced location.
Preserve the existing locale-specific wording and JSON structure.
| "metaDescription": "oh-my-opencode(cmux omo)在 cmux 中运行带 oh-my-openagent 插件的 OpenCode CLI。将 Claude、GPT、Gemini 和 Grok 作为并行 agent 编排,每个都在独立的原生 cmux 分屏中。", | ||
| "metaDescriptionShort": "oh-my-opencode(cmux omo)在 cmux 中运行带 oh-my-openagent 插件的 OpenCode CLI。将 Claude、GPT、Gemini 和 Grok 作为并行 agent 编排,每个都在独立的原生 cmux 分屏中。" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
metaDescriptionShort duplicates metaDescription verbatim.
Both fields for ohMyOpenCode contain the exact same text. This provides no distinct short-form curated description and runs counter to the PR's own stated goal of rejecting duplicated SEO copy. Please author a genuinely shorter/distinct summary for metaDescriptionShort.
🤖 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/messages/zh-CN.json` around lines 1540 - 1541, Update the ohMyOpenCode
entry’s metaDescriptionShort to a genuinely shorter, distinct summary rather
than duplicating metaDescription, while preserving metaDescription unchanged and
keeping the short description’s core product and cmux context.
Stacked on #7888.
Routes 17 audited docs families through one metadata builder. HTML, Open Graph, Twitter, canonical URLs, and route-specific locale availability share one bounded copy selection.
Tests:
bun test(590 passed, 91 skipped),bun run typecheck, changed-file ESLint,SKIP_ENV_VALIDATION=1 bun run build.Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Note
Low Risk
SEO and metadata-only changes with no auth or runtime behavior; main risk is incorrect titles/descriptions or alternates on docs pages if message keys are wrong.
Overview
Routes 17 docs pages through a shared
auditedDocsMetadatahelper so HTML titles, descriptions, Open Graph, Twitter cards, and canonical/hreflang alternates all use the same bounded SEO pipeline (includingavailableLocalesfor remote-tmux).docsPageSeoCopynow picks docs titles without stacking layout taglines, uses a separatesocialTitlefor OG/Twitter, and builds descriptions only frommetaDescriptionShort, the first complete sentence ofmetaDescriptionorintro, with stricter punctuation rules (e.g. Khmer៖). Locale files gainmetaDescriptionShort(and some copy tweaks) where needed.seo.test.tsextends audits so rendered titles include the docs layout suffix and descriptions stay within 110–160 snippet units.Reviewed by Cursor Bugbot for commit c81e844. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Centralizes docs SEO metadata with a single helper and enforces audited, route‑specific descriptions across 17 pages. Titles stay within bounds without stacking the docs layout suffix; Open Graph/Twitter use a separate social title.
Bug Fixes
metaDescriptionShort, then the first complete sentence ofmetaDescriptionorintro; ignore headings; reject HTML/rich text and{…}placeholders; trim trailing colons (incl. Khmer៖); reject truncated or generic fragments; keep copy tied to the route.socialTitleindependently; fix canonical/hreflang alternates and restrictremote-tmuxlocales; make width checks deterministic.Refactors
web/app/[locale]/(landing)/docs/audited-docs-metadata.ts; replace per‑pagegenerateMetadataacross all 17 docs routes; passavailableLocalesforremote-tmux.docsPageSeoCopyto select compact titles (e.g., oh-my-opencode), use complete metadata sentences, and disable auto context viaseoTitle({ appendLocalizedContext: false }); addmetaDescriptionShortto locales and extend tests for docs metadata regressions and Khmer punctuation.Written for commit c81e844. Summary will update on new commits.
Summary by CodeRabbit
New Features
Bug Fixes
Tests