Point both overview nav slots at the canonical concept pages - #58
Conversation
Co-Authored-By: bot_apk <apk@cognition.ai>
Co-Authored-By: bot_apk <apk@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
| } | ||
| if (!value || typeof value !== "object") return; | ||
| for (const [key, child] of Object.entries(value)) { | ||
| visit(child, key === "pages"); |
There was a problem hiding this comment.
The collector only recognizes strings under pages, while this repository also uses root for navigated page references. An alias targeting a root page such as deploy/aws is therefore reported as absent from navigation, causing the new CI check to reject valid metadata.
| visit(child, key === "pages"); | |
| visit(child, key === "pages" || key === "root"); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/check-canonical-noindex.mjs
Line: 67
Comment:
**Navigation roots are omitted**
The collector only recognizes strings under `pages`, while this repository also uses `root` for navigated page references. An alias targeting a root page such as `deploy/aws` is therefore reported as absent from navigation, causing the new CI check to reject valid metadata.
```suggestion
visit(child, key === "pages" || key === "root");
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Good catch — docs.json does use root for navigated group landing pages (deploy/aws, module-definitions/standard-library, module-definitions/definition-schema), so an alias canonicalizing to one of those would have been rejected. Fixed in 9f380a6, with a test covering a canonical target that only appears as a group root.
Co-Authored-By: bot_apk <apk@cognition.ai>
Replace the /modules/overview and /pipelines/overview alias pages with the canonical concept pages in both navigation locations, redirect the legacy URLs permanently, and enforce the SEO invariants in a check script.
Summary
/docs/modules/overviewand/docs/pipelines/overviewwere duplicate alias pages: each rendered the same shared snippet as its canonical concept page (/docs/concepts/modules,/docs/concepts/pipelines) and each appeared in the generated sitemap, so the sitemap advertised two indexable URLs per topic.The aliases are gone. Their two sidebar slots now point at the canonical pages instead, so the same page path appears in two navigation locations:
{ "group": "Modules", "pages": [ - "modules/overview", + "concepts/modules", "modules/stack", ... { "group": "Pipelines", "pages": [ - "pipelines/overview", + "concepts/pipelines", "pipelines/examples", ...Legacy URLs keep working via
docs.jsonredirectswithpermanent: true, and internal links (plus the assistant skill citation) were repointed at the canonical paths.No page ends up with
noindexor a cross-pagecanonical: the sitemap now contains one indexable URL per topic because only one page exists per topic.scripts/check-docs-seo-invariants.mjs(replacingcheck-canonical-noindex.mjs, wired into CI andpnpm test) fails the build if a future change reintroduces the problem shape:noindex/hiddennoindex: true, or acanonicalpointing at a different pagePlatform behavior worth knowing
permanent: falsegives 307. A literal 301 isn't configurable. Google treats 308 as equivalent to 301 for consolidating ranking signals.noindex: truekeeps a page in the nav but drops it from the sitemap, andhidden: truedrops it from both. There is no way to keep an alias in the nav, indexable, and out of the sitemap — which is why the aliases were removed outright rather than kept withrel=canonicalonly.pagesentries are page paths with no per-entry label override, so the two slots now render the canonical page'ssidebarTitle("Modules" / "Pipelines") where they previously read "Overview". Placement and discoverability are unchanged.Verification
mint validateandmint broken-linksboth pass;mint devserves the redirects (307 locally — the dev server doesn't applypermanent; hosted Mintlify serves 308). Invariant check,node --test scripts/*.test.mjs(10 passing), and the OG image check all pass.Both nav locations render and resolve to the single canonical URL:
mint devdoes not servesitemap.xml(404 locally), so the sitemap and the real redirect status come from this PR's Mintlify preview deployment:Link to Devin session: https://app.devin.ai/sessions/77b84201f8324d089aae372d6ed87da1