Skip to content

fix(import): homepage docs-route probe trailing slash + SPA catch-all - #39

Merged
minhthanhdang merged 1 commit into
mainfrom
minh/rm-17864-importer-bare-homepage-imports-marketing-skeleton-docs-route
Aug 11, 2026
Merged

fix(import): homepage docs-route probe trailing slash + SPA catch-all#39
minhthanhdang merged 1 commit into
mainfrom
minh/rm-17864-importer-bare-homepage-imports-marketing-skeleton-docs-route

Conversation

@minhthanhdang

@minhthanhdang minhthanhdang commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Context

Importing a bare homepage (e.g. https://malveon.com, https://turbopaybd.com) produced a marketing-site skeleton instead of the doc site. Two root causes in resolveDocsBaseUrl's existence probe:

  1. Trailing slash: the probe fetches https://site/docs/; many sites 301 to /docs (slash stripped). inCandidateScope compared with startsWith("/docs/"), so the correct route was rejected as an out-of-scope alias.
  2. SPA catch-all: some sites return 200 + the marketing shell for ANY unknown path, so the first well-known route (/docs/) was adopted over the real docs route ranked later (/developers/).

Changes

  • inCandidateScope now strips trailing slashes and compares on segment boundaries: /docs matches the /docs/ candidate, while / and /docsomething stay rejected. The apex→www host hop for path candidates is preserved.
  • Soft-404 detection: before the existence probes, fetch one guaranteed-nonexistent path on the origin and capture its normalized <title>. A path candidate whose title equals that baseline is a catch-all response and is skipped with an explicit log line. Sites that 404 properly (or have no title) produce no baseline, so healthy sites are never falsely rejected.
  • docsRouteResolves returns { exists, soft404 }; the body is only read for path candidates when a baseline exists.

Verification

  • npm test: 102/102 pass, including new coverage for slash-redirect adoption, redirect-to-homepage rejection, catch-all skip, all-candidates-fail, and inCandidateScope boundary cases.
  • Live step:skeleton https://malveon.com: adopts https://www.malveon.com/docs/ and produces the full ~44-page doc skeleton (was: 9-page marketing skeleton).
  • Live step:skeleton https://turbopaybd.com: /docs/ and /doc/ are logged as indistinguishable from a nonexistent path (SPA catch-all) — skipping; /developers/ is adopted.

Pairs with https://github.com/readmeio/ai-cli-runner/pull/108, which handles the follow-on single-stub fallback; a sandbox snapshot rebuild is required to ship this CLI change.

🤖 Generated with Claude Code

…t-404 detection

Bare homepages whose /docs route 301s to a slash-stripped path were
rejected as out-of-scope aliases, and SPA catch-all sites adopted the
first well-known route even when it served the marketing shell. Scope
comparison now strips trailing slashes and enforces segment boundaries;
a soft-404 baseline title fetched from a garbage path rejects path
candidates indistinguishable from a nonexistent page.
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Documentation route discovery now detects SPA soft-404 responses by comparing candidate page titles with a guaranteed-invalid path. Route checks follow redirects, enforce candidate scope, and return structured resolution results. Candidate paths that match the site’s catch-all response are skipped. The exported test helpers now include inCandidateScope and resolveDocsBaseUrl. Tests cover redirects, homepage rejection, host and path boundaries, SPA catch-all responses, distinct content, and complete discovery failure.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 `@src/commands/import.js`:
- Around line 3578-3581: Update the path-candidate matching logic around strip
and the finalPath/candidatePath comparison to validate final.hostname first.
Accept only the candidate hostname or its permitted apex-to-www alias, then
retain the existing pathname match; reject unrelated hosts even when their paths
match, and add a regression test covering an unrelated hostname using /docs.
🪄 Autofix

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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 88175e0d-2da5-4412-9e29-811cb7446d1c

📥 Commits

Reviewing files that changed from the base of the PR and between 2c411b1 and fa9d991.

📒 Files selected for processing (2)
  • src/commands/import.js
  • src/commands/import.test.js
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • readmeio/ai (manual)
  • readmeio/gitto (manual)
  • readmeio/markdown (manual)
  • readmeio/readme (manual)

Comment thread src/commands/import.js
@minhthanhdang minhthanhdang changed the title RM-17864: Fix homepage docs-route probe (trailing slash + SPA catch-all) fix: homepage docs-route probe (trailing slash + SPA catch-all) Aug 10, 2026
@minhthanhdang minhthanhdang changed the title fix: homepage docs-route probe (trailing slash + SPA catch-all) fix(import): RM-17864 homepage docs-route probe trailing slash + SPA catch-all Aug 10, 2026
@minhthanhdang minhthanhdang changed the title fix(import): RM-17864 homepage docs-route probe trailing slash + SPA catch-all fix(import): homepage docs-route probe trailing slash + SPA catch-all Aug 10, 2026

@xavierandueza xavierandueza left a comment

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.

Nice work - LGTM.

Comment thread src/commands/import.js
Comment on lines +3591 to +3597
/**
* Fetch a guaranteed-nonexistent path and capture its page title. On SPA
* catch-all sites every unknown path returns 200 with the same shell page;
* that title becomes the soft-404 baseline. Returns null when the site 404s
* properly (no baseline needed) or on any fetch failure.
*/
async function fetchSoft404Title(origin) {

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.

good thinking to do this, neat trick.

@minhthanhdang
minhthanhdang merged commit 0b01be7 into main Aug 11, 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.

2 participants