Copy/Download Button Feature
A reusable feature that adds a copy/download button to the top of every documentation page, positioned next to the breadcrumbs. Users can copy page content as plaintext or markdown, or download the page as a markdown file.
Features
- Copy Plaintext - Extracts and copies the page content as plain text
- Copy Markdown - Converts HTML content to markdown format and copies to clipboard
- Download Markdown - Downloads the page content as a
.mdfile with the page title as the filename - Dropdown Menu - Clean dropdown interface with visual feedback
- Responsive Design - Adapts to mobile and desktop layouts
- Accessibility - Includes proper ARIA attributes and keyboard navigation
Installation
The feature is already set up in this repository. For new repositories, see the Setup Guide below.
How It Works
The button appears automatically on all documentation pages (.md files) in the top-right area, next to the breadcrumbs. It uses:
- DocItem Wrapper - Swizzled
DocItemcomponent that injects the button - CopyDownloadButton Component - React component that handles the copy/download functionality
- Raw Markdown Fetching - Fetches the original markdown source file from GitHub (or source repository)
- HTML to Markdown Fallback - Falls back to HTML-to-markdown conversion if raw file is unavailable
- Clipboard API - Uses the browser's Clipboard API for copying content
- File Download - Creates a downloadable
.mdfile for the download option
Usage
The button is automatically available on all documentation pages. No configuration needed.
User Experience
- Click the "Copy" button next to the breadcrumbs
- Select from the dropdown:
- Copy - Plaintext: Copies the page content as plain text
- Copy - Markdown: Copies the page content as markdown
- Download - Markdown: Downloads the page as a
.mdfile
Visual Feedback
- Button shows "Copied!" message for 2 seconds after copying
- Dropdown closes automatically after selection
- Button includes hover and focus states for better UX
Technical Details
Component Structure
docusaurus/src/
├── components/
│ └── CopyDownloadButton/
│ ├── index.tsx # Main component
│ └── styles.module.css # Component styles
└── theme/
└── DocItem/
└── index.tsx # Swizzled wrapper that injects button
Raw Markdown Fetching
The component attempts to fetch the original markdown source file from GitHub using:
- The
editUrlfrom Docusaurus configuration - The document path constructed from the current page location
- GitHub's raw file URL format
If the raw markdown file is successfully fetched, it's used directly for copy/download operations, ensuring perfect markdown formatting.
HTML to Markdown Fallback
If the raw markdown file cannot be fetched (e.g., in development, or if the file path cannot be determined), the component falls back to a simplified HTML-to-Markdown converter that handles:
- Headings (h1-h6)
- Paragraphs
- Bold and italic text
- Code blocks and inline code
- Lists (ordered and unordered)
- Links
- Images
- Blockquotes
- Tables
- Horizontal rules
Note: The HTML-to-markdown conversion is simplified and may not handle all edge cases perfectly. The raw markdown option provides the most accurate results.
Browser Compatibility
- Requires modern browser with Clipboard API support
- Falls back gracefully if Clipboard API is unavailable
- Works in all modern browsers (Chrome, Firefox, Safari, Edge)
Setup Guide
For New Repositories
-
Copy the component files:
docusaurus/src/components/CopyDownloadButton/index.tsxdocusaurus/src/components/CopyDownloadButton/styles.module.css
-
Swizzle the DocItem component:
npm run swizzle @docusaurus/theme-classic DocItem --wrap --typescript --danger -
Update the DocItem wrapper: Edit
docusaurus/src/theme/DocItem/index.tsxto include:import CopyDownloadButton from '@site/src/components/CopyDownloadButton';
// Add useEffect to inject button (see source file for full implementation) -
Add CSS styles: Copy the CSS from
docusaurus/src/css/custom.cssrelated to.copy-download-button-injected -
Test the feature:
- Start the dev server:
npm start - Navigate to any documentation page
- Verify the button appears next to breadcrumbs
- Test all three options (copy plaintext, copy markdown, download markdown)
- Start the dev server:
Customization
Styling
The button styles can be customized by modifying:
docusaurus/src/components/CopyDownloadButton/styles.module.css- Component-specific stylesdocusaurus/src/css/custom.css- Positioning and layout styles
Button Position
The button is positioned using CSS. To change its position, modify the styles in custom.css:
.copy-download-button-injected {
position: absolute;
top: 0;
right: 0; /* Change to 'left' for left alignment */
z-index: 10;
}
Button Text
To change the button text, edit docusaurus/src/components/CopyDownloadButton/index.tsx:
<span className={styles.buttonText}>Copy</span> // Change "Copy" to your preferred text
Limitations
-
Raw Markdown Availability: The raw markdown fetch requires:
- The page to be accessible via GitHub (or configured source repository)
- The
editUrlto be properly configured indocusaurus.config.ts - Network access to fetch the file
- The file path to be correctly constructed from the page location
-
HTML-to-Markdown Fallback: If raw markdown is unavailable, the HTML-to-Markdown conversion is simplified and may not perfectly preserve all formatting, especially for complex nested structures
-
MDX Components: Content from custom MDX components may not convert perfectly to markdown in the fallback mode
-
Dynamic Content: Only static content is captured; dynamically generated content may not be included
Best Practices
- Raw Markdown is Preferred: The component automatically fetches raw markdown when available, providing the most accurate results
- Use Plaintext for Simple Content: For basic text extraction, the plaintext option is most reliable
- Configure editUrl: Ensure
editUrlis properly configured indocusaurus.config.tsto enable raw markdown fetching - Test on Different Pages: Verify the feature works correctly on pages with various content types (code blocks, tables, lists, etc.)
- Network Access: Raw markdown fetching requires network access to GitHub; ensure your deployment environment has this access
Related Documentation
- Docusaurus Swizzling - How to customize theme components
- DocItem Component - Documentation on the DocItem component
- Clipboard API - Browser Clipboard API documentation