Add copy-as-Markdown action to documentation pages#375
Conversation
|
📦 Preview · View → · 🟢 Live Verified for |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: be80473302
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Add a copy-for-LLM button and "View page as markdown" / "Use in your agent" dropdown to every documentation page. The button copies the page's Markdown twin to the clipboard; the menu links open the same content for human or agent consumption. Decouple the per-page `.md` route from the `LLMS_TXT` env flag via a new plugin option, so the action works in normal dev and production builds. The site-wide `/llms.txt` and `/llms-full.txt` routes stay gated behind the flag. Add a shared `markdownPathForDocPath` / `markdownUrlForDocPath` helper so the per-page route, the copy URL in PageTitle, and link rewriting in entry-to-markdown agree on slug normalization (`*/index` → `*`). Move changelog topics behind an `import.meta.glob` loader so the per-page route survives fresh checkouts where the generated `sidebar-changelog.generated.ts` is absent. Assisted-by: Claude Opus 4.7 (Claude Code)
OpenAPI pages (`/reference/{node,platform}/api/...`) render via
PageTitle but are not part of the `docs` content collection, so the
plugin generates no `.md` route for them. Clicking the copy or view
button would 404.
Gate the action buttons on `docsMap.has(starlightRoute.entry.id)` so
they only appear on pages backed by the collection. Future
integrations that inject pages outside the collection are covered by
the same check.
Assisted-by: Claude Opus 4.7 (Claude Code)
The button JS used to fire a fetch for the page's Markdown twin on every page load and kept the copy button disabled until the response arrived. Most readers never use the copy action, so this was one extra page-sized request per view, and on slow links the action was unavailable until the prefetch settled. Flip the SSR-disabled buttons to idle on JS init without fetching. The existing pointerover and focusin listeners already prefetch on user intent, and the click handler fetches inline when the cache is empty. Assisted-by: Claude Opus 4.7 (Claude Code)
b4de13f to
19841e5
Compare
Internal links in the generated `.md` were root-relative (`/foo.md`) while the appended `## Contents` section was absolute (`https://docs.tenzir.com/foo.md`). The mismatch was awkward and the relative form was the wrong default: an LLM or agent reading a copied page has no origin to resolve `/foo.md` against. Wrap the rehype/remark pipeline in a per-baseUrl factory with a small cache, and have the link rewriter prepend the site URL. Non-markdown internal paths (redirects like `/discord`, OpenAPI roots) are absolutised too without appending `.md`. Assisted-by: Claude Opus 4.7 (Claude Code)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 02d7a9b2d3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const cleanPath = path.endsWith("/") ? path.slice(0, -1) : path; | ||
| link.properties.href = `${cleanPath}.md${suffix}`; | ||
| link.properties.href = `${markdownUrlForDocPath(baseUrl, cleanPath)}${suffix}`; |
There was a problem hiding this comment.
Strip the configured base before rewriting Markdown links
When the docs are built with --base (which this repo explicitly supports in astro.config.mjs), rendered internal anchors have already been prefixed by rehypeBaseLinks, e.g. /preview/guides/quickstart/, while baseUrl also resolves to https://docs.tenzir.com/preview. Passing that prefixed path into markdownUrlForDocPath() produces links like https://docs.tenzir.com/preview/preview/guides/quickstart.md, so copied/generated per-page Markdown contains broken internal links for base-path deployments. Strip the configured base from cleanPath before treating it as a doc path.
Useful? React with 👍 / 👎.
🔍 Problem
.mdroute was gated behindLLMS_TXT=true, so any UI exposing those URLs would 404 in normal dev/prod builds.🛠️ Solution
<h1>row.llmsTxtandperPageMarkdowngates so the.mdtwin is always available; the site-wide/llms.txtand/llms-full.txtstay gated.PageTitle, and link rewriting inentry-to-markdownagree on*/index→*.import.meta.globso the per-page route works on fresh checkouts wheresidebar-changelog.generated.tsis absent.💬 Review
getStaticPathsnow normalisesdoc.idfor the slug (e.g.guides/index→guides). Old/guides/index.md-shaped URLs no longer exist — only matters if anything external bookmarks them.import.meta.globwitheager: trueis the deliberate choice overtry/catch import():sitemap-generator.tsconsumes topics in a sync context, and the eager glob handles the missing-file case without a runtime check.starlight-site-navigationstill uses its ownfs+regexloader for the changelog (needs bothchangelogTopicsandchangelogTopicPaths); left out of scope.copy,chevron-down,file-text,bot). Breadcrumb home/chevron icons were left as-is — pre-existing, hand-inlined to the same style.