Skip to content

docs: add docusaurus-plugin-copy-page-button#6462

Open
portdeveloper wants to merge 3 commits into
cypress-io:mainfrom
portdeveloper:add-docusaurus-copy-page-button
Open

docs: add docusaurus-plugin-copy-page-button#6462
portdeveloper wants to merge 3 commits into
cypress-io:mainfrom
portdeveloper:add-docusaurus-copy-page-button

Conversation

@portdeveloper

@portdeveloper portdeveloper commented May 21, 2026

Copy link
Copy Markdown

Summary

https://github.com/portdeveloper/docusaurus-plugin-copy-page-button

  • add docusaurus-plugin-copy-page-button to the docs dependencies
  • register the plugin in docusaurus.config.js

Why

Cypress docs include testing guides, API pages, and examples that developers often bring into AI tools. This adds a page-level copy/open button that exports the current page as clean markdown and includes one-click Open in ChatGPT, Claude, and Gemini actions.

I checked the repo for overlapping features before opening this. Cypress already publishes LLM-readable markdown exports under /llm plus llms.txt. This PR is different: it adds a page-level UI action for copying or opening the current page directly from the docs page.

The plugin has no runtime dependencies and uses peer dependencies for Docusaurus and React.

Validation

  • git diff --check
  • package manifest, lockfile, and config sanity check

Not run locally: full docs build, due the dependency install/build footprint in this environment.


Note

Low Risk
Docs-only UI and dependency wiring; no changes to auth, APIs, or content generation beyond reusing existing LLM markdown URLs.

Overview
Adds docusaurus-plugin-copy-page-button so readers can copy, view, or open the current doc page in ChatGPT or Claude from the table of contents sidebar.

The plugin is registered with injectButton: false and the button is placed manually in the swizzled TOC theme. markdownUrl points at the existing /llm/markdown/... paths from the site’s LLM export plugin, so actions reuse published markdown rather than a new export path. Minor CSS styles the control in the TOC header.

Reviewed by Cursor Bugbot for commit e366f18. Bugbot is set up for automated code reviews on this repo. Configure here.

@netlify

netlify Bot commented May 21, 2026

Copy link
Copy Markdown

👷 Deploy request for cypress-docs pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit e366f18

@CLAassistant

CLAassistant commented May 21, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@cypress-app-bot

Copy link
Copy Markdown
Collaborator

@portdeveloper

Copy link
Copy Markdown
Author

Quick note: I used my agents to help generate this PR. Feel free to tag me (@portdeveloper) in this thread with any questions and I'll reply asap 🙏

@portdeveloper

Copy link
Copy Markdown
Author

Friendly nudge on this PR — happy to address any feedback if it'd help land it. The plugin recently shipped on react/react-native-website#5085 and continues to see adoption. Thanks for your time!

@jennifer-shehane

Copy link
Copy Markdown
Member

@portdeveloper Cool, thanks for the suggestion, we'll have someone evaluate this soon. Thanks!

@emilyrohrbough

Copy link
Copy Markdown
Member

@portdeveloper a couple of questions:

  • What other changes are you planning before releasing this as a v1?
  • We already have /llm content. Have you considered adding a config option to use the llm.txt links in the "Open in Claude" quick links? We don't need generateMarkdownRoutes: true.
  • Is it possible to assign a data attribute to the injected button so we can track interactions to measure how useful this is?

Testing this locally, I tried configuring both injection locations because auto-inject was not consistently rendering the copy button in the same location, leading to odd, unexpected behaviors.

The article injection location (unstyled) took away from the actual content by pushing it down and make it appear like the most important first thing to look at.

The content inject would align better with where I'd expect this to be a meaningful attention. The button is being injected between the content section title and TOC.
Screenshot 2026-06-01 at 11 28 49 AM

@portdeveloper

Copy link
Copy Markdown
Author

Thanks this is great feedback, will address them asap

@portdeveloper

Copy link
Copy Markdown
Author

shipped all three requested features in 0.8.0, so you can bump and test.

markdownUrl: new option, separate from generateMarkdownRoutes. set markdownUrl: true and the "Open in Claude/ChatGPT/…" links point at your existing /path.md instead of the html page, plugin generates nothing. what's the exact url shape of your md? built-in true maps /foo/bar//foo/bar.md — if yours differs (e.g. a /llms/ prefix) tell me and i'll match it.

tracking: every action now fires a copy-page-button:action event on document with { action, url } for analytics. items also carry data-copy-page-action="…" if you'd rather delegate off the dom.

placement: you found a real bug — under auto, if the toc hadn't mounted on the first attempt the button got stuck inline for the rest of the page, and that timing varied per load (hence the inconsistency). fixed: it migrates into the toc once the sidebar appears. for your site i'd just set placement: "toc" to pin it to the right rail.

before v1: lock the options above + an SSR/swizzle mode that renders the button in static html so placement never depends on client injection (the real fix for the above; the migration is interim).

happy to tweak any of it 🙏

@portdeveloper

Copy link
Copy Markdown
Author

hey @emilyrohrbough — following up on the three asks: 0.8.0 shipped all of them (the markdownUrl option so the "open in…" links point at your existing /llm content, the interaction tracking hooks, and the deterministic placement). whenever you get a chance to bump + test, happy to help if anything's off. no rush 🙏

@emilyrohrbough

Copy link
Copy Markdown
Member

@portdeveloper Hey! Thanks for the bump. I missed your original response. I'll add this to my list to review today!

Comment thread docusaurus.config.js Outdated
],
require.resolve('docusaurus-plugin-image-zoom'),
require.resolve('./plugins/llm'),
'docusaurus-plugin-copy-page-button',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
'docusaurus-plugin-copy-page-button',
[
"docusaurus-plugin-copy-page-button",
{
injectButton: false,
},
],

@emilyrohrbough emilyrohrbough Jun 10, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Then an we add this to cypress-documentation/src/theme/TOC/index.tsx so this is rendered nicely before the TOC. right now it's inject between the title & content

export default function TOCWrapper(props) {
  return (
    <>
+      <div style={{display: "flex", justifyContent: "flex-end"}}>
+        <CopyPageButton
+          enabledActions={['copy', 'view', 'claude', 'chatgpt']}
+          markdownUrl={(url) => {
+            const { protocol, hostname, port, pathname } = new URL(url);
+            const llmRoute = [
+              protocol,
+              '//',
+              hostname,
+              port ? `:${port}` : '',
+              '/llm/markdown/',
+              pathname,
+              '.md'
+            ].join('');
+            return llmRoute
+          }}
+          customStyles={{
+            button: { className: styles.copyPageButton }
+          }}
+        />
      </div>
      <h2 className="border-l border-gray-1000/[.07] dark:border-gray-900 my-0 pb-[12px] pl-[1.5rem] text-gray-700 font-medium uppercase text-[16px]">
        Contents
      </h2>
      <TOC
        {...props}
        className={clsx(
          props.className,
          'table-of-contents__left-border pt-[.1rem] table-of-contents'
        )}
      />
    </>
  )
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And these styles should align the button with ours:

.copyPageButton {
  background: transparent !important;
  border-radius: 4px;
  font-size: 0;
  gap: 4px;
  margin-bottom: 0;
  padding: 8px;
  height: 32px;
}

- disable auto-injection (injectButton: false)
- render <CopyPageButton> above the TOC via the existing swizzle
- point markdownUrl at the /llm/markdown/*.md routes
- align styling with the docs theme
@portdeveloper

Copy link
Copy Markdown
Author

done — pushed all three:

  • injectButton: false in the plugin config
  • rendering <CopyPageButton> in the TOC swizzle above the contents heading, with enabledActions={['copy','view','claude','chatgpt']} and the customStyles className
  • the .copyPageButton styles in a styles.module.css next to the swizzle

one tweak to your markdownUrl snippet: new URL(url).pathname keeps the leading slash, so joining it straight after /llm/markdown/ gave a double slash (/llm/markdown//app/...) that 404s. i strip the leading/trailing slash and fall back to index.md for the root:

markdownUrl={(pageUrl) => {
  const {origin, pathname} = new URL(pageUrl)
  const rel = pathname.replace(/^\/+/, '').replace(/\/+$/, '')
  return `${origin}/llm/markdown/${rel ? `${rel}.md` : 'index.md'}`
}}

built locally and the button renders before the TOC, styles match, and the open-in-LLM links resolve to your real /llm/markdown/*.md files (checked a handful). should be good in the deploy preview — thanks for the detailed pointers!

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.

6 participants