feat(docs): add per-page .md endpoint and Copy MD button#379
feat(docs): add per-page .md endpoint and Copy MD button#379ParwarYasinQadr wants to merge 2 commits into
Conversation
Appending .md to any docs URL returns the page as clean markdown, making it easy for users and AI tools to feed docs into LLMs. - Adds /llms.mdx/[[...slug]]/route.ts handler with CORS + cache headers - Adds /:path*.md → /llms.mdx/:path* rewrite in next.config.mjs - Configures includeProcessedMarkdown with a custom stringify that drops inline SVGs, unwraps JSX wrappers (Cards, fd-step divs, CodeBlockTabs), renders Callouts as blockquotes, and preserves tab labels so output is real markdown rather than raw MDX - Adds Copy MD button + Open-in dropdown on every docs page, styled with Fumadocs theme tokens
|
@ParwarYasinQadr is attempting to deploy a commit to the Convex Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: get-convex/coderabbit/.coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR adds markdown export functionality to the documentation site. Users can now append .md to any docs URL to fetch clean, LLM-ready markdown. The implementation involves custom MDX postprocessing rules that transform interactive elements (cards, callouts, tabs) into markdown equivalents, text normalization to clean whitespace and strip internal markers, a new route handler exposing markdown via /*.md URLs with appropriate headers, a client-side copy-to-clipboard component with feedback UI, and integration into the docs page layout with URL computation helpers. Sequence Diagram(s)sequenceDiagram
participant Browser
participant CopyButton as CopyMarkdownButton
participant Fetch as BrowserFetch
participant NextRewrite as Next.js Rewrite
participant RouteHandler as /llms.mdx/[[...slug]] Route
participant Source as source.getPage
participant TextNorm as getLLMText
Browser->>CopyButton: user clicks "Copy MD"
CopyButton->>Fetch: fetch(/path/to/page.md)
Fetch->>NextRewrite: GET /path/to/page.md
NextRewrite->>RouteHandler: rewrite → GET /llms.mdx/path/to/page
RouteHandler->>Source: source.getPage(slug)
Source-->>RouteHandler: page
RouteHandler->>TextNorm: getLLMText(page)
TextNorm-->>RouteHandler: formatted markdown
RouteHandler-->>Fetch: 200 text/markdown
Fetch-->>CopyButton: response text
CopyButton->>Browser: writeText(markdown) → clipboard
CopyButton-->>Browser: show "Copied" UI
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@docs/components/copy-markdown.tsx`:
- Around line 54-57: The handleCopyLink function should mirror
handleCopyMarkdown's error handling: wrap the
navigator.clipboard.writeText(fullUrl()) call in a try/catch, await it inside
try, call flash(setLinkCopied, () => setOpen(false)) on success, and in catch
log or otherwise handle the error (e.g., console.error or use existing logger)
to avoid unhandled promise rejections; update the handleCopyLink function
(references: handleCopyLink, fullUrl, navigator.clipboard.writeText, flash,
setLinkCopied, setOpen) accordingly.
In `@docs/lib/get-llm-text.ts`:
- Around line 14-18: stripDropMarkers currently only filters out lines that
consist solely of the drop marker, leaving marker characters embedded in
non-empty lines; update the stripDropMarkers function to remove the marker
character globally instead: within stripDropMarkers, replace all occurrences of
the marker character (the visible character in the regex /^\s*+\s*$/ used
previously) across the entire text (e.g., using a global replace) and then trim
or collapse any resulting empty lines if needed so no invisible marker artifacts
remain in output markdown.
🪄 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: Repository: get-convex/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 386950ff-a523-4b5b-b61b-d3b36a0b2539
📒 Files selected for processing (6)
docs/app/(home)/[[...slug]]/page.tsxdocs/app/llms.mdx/[[...slug]]/route.tsdocs/components/copy-markdown.tsxdocs/lib/get-llm-text.tsdocs/next.config.mjsdocs/source.config.ts
- Wrap handleCopyLink in try/catch to match handleCopyMarkdown's error handling and avoid unhandled promise rejections on clipboard permission denial - Strip zero-width-space drop markers globally instead of only on whole-marker lines, so embedded markers can't survive in output
Closes #378
Appending
.mdto any docs URL returns the page as markdown. Useful for piping docs into Claude/ChatGPT/Cursor without scraping HTML./better-auth/basic-usage/authorization → renders normally
/better-auth/basic-usage/authorization.md → raw markdown
Also added a Copy MD button + Open in ▾ dropdown (Copy markdown link / Open in new tab) in the top-right of every docs page, styled with
Fumadocs theme tokens.
Changes:
source.config.ts: enabledincludeProcessedMarkdownwith a custom stringify so the output is actual markdown. Strips inline SVGs,unwraps
<Cards>/<Callout>/<CodeBlockTabs>/ fd-step divs, renders Callouts as blockquotes, keeps tab labels.lib/get-llm-text.ts: formats# Title (/url)+ description + bodyapp/llms.mdx/[[...slug]]/route.ts: route handler. Statically prerendered for every page, withAccess-Control-Allow-Origin: *and a1h browser / 24h CDN cache.
next.config.mjs: rewrite/:path*.md→/llms.mdx/:path*components/copy-markdown.tsx: Copy button + Radix popover dropdown. Uses Fumadocs UI's transitive deps so no new packages.Tested locally across all 25 docs pages, regular site still renders, unknown paths 404, build clean.
Skipped
llms.txt/llms-full.txtto keep the PR focused — happy to follow up in a separate one if useful.