Skip to main content

Getting Started

Install the plugin in your Docusaurus project:

npm install docusaurus-plugin-copy-page-button

Then add it to your docusaurus.config.js:

module.exports = {
plugins: ['docusaurus-plugin-copy-page-button'],
};

That's it. The copy button automatically appears in the table-of-contents sidebar on every docs page. On narrow screens or pages without a table of contents, it falls back to the top of the article column.

Try It Now

You can see the button in action on this very page — look for the Copy page button in the right sidebar. The dropdown offers:

  • Copy page — copies the page as clean markdown to your clipboard
  • View as Markdown — opens the extracted markdown in a new tab
  • Open in ChatGPT — sends the page to ChatGPT with a pre-filled prompt
  • Open in Claude — sends the page to Claude with a pre-filled prompt
  • Open in Perplexity — sends the page to Perplexity with a pre-filled prompt
  • Open in Gemini — sends the page to Gemini with a pre-filled prompt

Requirements

  • Docusaurus 3.0+ — listed as a peer dependency. The plugin uses APIs introduced in Docusaurus 3 (Translate, @theme-original-style swizzling).
  • React 18 or 19 — peer dependency ^18.0.0 || ^19.0.0.
  • Node 18+ for the build toolchain.

If you're still on Docusaurus 2.x, the plugin won't load. Upgrade your site first using the official Docusaurus 3 migration guide.

Upgrading

0.6.x → 0.7.x

0.7.0 adds full localization support (labels plugin option + Docusaurus <Translate> integration). The change is backward-compatible — default English text is unchanged.

If you want to translate the labels, see the Localization guide. Otherwise, just bump the version:

npm install docusaurus-plugin-copy-page-button@^0.7.0

No config changes required.

0.5.x → 0.6.x

0.6.0 added Perplexity as a default AI action and introduced MCP server actions. If you pinned enabledActions to an explicit list, add 'perplexity' if you want it visible:

enabledActions: ['copy', 'view', 'chatgpt', 'claude', 'perplexity', 'gemini']

Troubleshooting

The button doesn't appear

Most common causes, in order:

  1. You're not on a doc page. Auto-injection only targets pages rendered by @docusaurus/plugin-content-docs. The homepage (src/pages/index.tsx) and other custom pages don't get the button by default — use the Swizzled placement recipe to put it on custom pages.
  2. The sidebar/TOC selectors didn't match. Heavily themed sites can move the TOC into a non-standard DOM location. Set placement: 'article' to render the button at the top of the article column instead, or render the React component manually.
  3. You set injectButton: false but didn't render the component. Auto-injection is required unless you're manually rendering. Set it back to the default (true) or follow Swizzled placement.
  4. You're testing in a <noscript> snapshot. The button is React-rendered on the client; it doesn't appear in raw server-side HTML. Open the page in a browser, not via curl.

The dropdown opens in the wrong position

Versions 0.6.1 and 0.6.2 fixed positioning regressions. Make sure you're on ^0.6.2 or newer:

npm install docusaurus-plugin-copy-page-button@latest

"Open in ChatGPT/Claude/etc." does nothing

The AI deep-links call window.open(url, '_blank'). If clicking does nothing:

  1. Pop-up blocker. Check the browser's address bar for a "pop-up blocked" indicator. Most browsers allow pop-ups when the click is a direct user gesture, but some extensions override this.
  2. CSP frame-src blocking external origins. If your site sets a strict Content-Security-Policy, the new tab might be silently blocked.
  3. Sandbox attributes on the page's <iframe>. If your docs page is embedded in an iframe without allow-popups, window.open fails silently.

A quick test: open the browser DevTools Console and click the failing action. The plugin currently swallows errors silently — if you see no console output but no new tab either, the cause is almost certainly the browser refusing the popup.

Copy page works but View as Markdown doesn't

View as Markdown creates a Blob URL and opens it. Some sandboxed environments (corporate browsers, certain iframes) block blob: URLs. Workaround: set generateMarkdownRoutes: true so the markdown is served from a real URL instead of a blob.

The labels are still in English on my translated locale

Two things to verify:

  1. You're using a non-default locale. Docusaurus's <Translate> only swaps strings when the active locale differs from defaultLocale. If you set defaultLocale: 'ja', English labels won't appear regardless of code.json overrides.
  2. Your i18n/<locale>/code.json has the plugin's IDs. docusaurus write-translations does not extract them from node_modules — you have to add them manually. See the Localization page for the full ID table.

Where next