🔧 fix: change markdown button to copy to clipboard#777
🔧 fix: change markdown button to copy to clipboard#777Aqua-123 wants to merge 1 commit intoelysiajs:mainfrom
Conversation
WalkthroughThe layout component now copies page Markdown to clipboard via a new button instead of opening it in a new tab. A copyMarkdownToClipboard() function fetches and copies the Markdown with error handling. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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: 1
🧹 Nitpick comments (1)
docs/.vitepress/theme/layout.vue (1)
200-206: LGTM! Semantic improvement from link to button.The conversion from
<a>to<button>is semantically correct—buttons should trigger actions (copy), while links navigate. The title update clearly communicates the new behavior.Optional: Add explicit type="button"
As a defensive best practice, explicitly set
type="button"to prevent potential form submission if the component is ever used in a form context:<button @click="copyMarkdownToClipboard" class="clicky" title="Copy as Markdown" + type="button" > <File stroke-width="1.5" /> </button>
| async function copyMarkdownToClipboard() { | ||
| const mdUrl = `https://elysiajs.com${router.route.path.replace(/.html$/g, '')}.md` | ||
| try { | ||
| const response = await fetch(mdUrl) | ||
| const markdown = await response.text() | ||
| await navigator.clipboard.writeText(markdown) | ||
| } catch (error) { | ||
| console.error('Failed to copy markdown:', error) | ||
| } | ||
| } |
There was a problem hiding this comment.
Critical: Hardcoded production URL breaks local development.
The function hardcodes https://elysiajs.com which will fail when developers run the site locally. During development, the fetch should resolve to the local dev server, not production.
Additionally, there's no user feedback—users won't know whether the copy succeeded or failed (only console logs).
🔧 Proposed fixes
Fix 1: Use relative URL to support both dev and production
async function copyMarkdownToClipboard() {
- const mdUrl = `https://elysiajs.com${router.route.path.replace(/.html$/g, '')}.md`
+ const mdUrl = `${router.route.path.replace(/\.html$/, '')}.md`
try {
const response = await fetch(mdUrl)
+ if (!response.ok) throw new Error(`Failed to fetch: ${response.status}`)
const markdown = await response.text()
await navigator.clipboard.writeText(markdown)
+ console.log('✓ Markdown copied to clipboard')
} catch (error) {
console.error('Failed to copy markdown:', error)
}
}Fix 2: Add user feedback with timeout
async function copyMarkdownToClipboard() {
- const mdUrl = `https://elysiajs.com${router.route.path.replace(/.html$/g, '')}.md`
+ const mdUrl = `${router.route.path.replace(/\.html$/, '')}.md`
try {
- const response = await fetch(mdUrl)
+ const controller = new AbortController()
+ const timeoutId = setTimeout(() => controller.abort(), 10000)
+ const response = await fetch(mdUrl, { signal: controller.signal })
+ clearTimeout(timeoutId)
+
+ if (!response.ok) throw new Error(`HTTP ${response.status}`)
const markdown = await response.text()
await navigator.clipboard.writeText(markdown)
+
+ // TODO: Add toast notification for success
+ console.log('✓ Markdown copied to clipboard')
} catch (error) {
console.error('Failed to copy markdown:', error)
+ // TODO: Add toast notification for error
}
}Notes:
- Removed the unnecessary
gflag from the regex (only one match at end of string) - Added response status check
- Fix 2 includes abort controller for 10-second timeout
- Consider adding visual feedback (toast/notification) instead of just console logs
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async function copyMarkdownToClipboard() { | |
| const mdUrl = `https://elysiajs.com${router.route.path.replace(/.html$/g, '')}.md` | |
| try { | |
| const response = await fetch(mdUrl) | |
| const markdown = await response.text() | |
| await navigator.clipboard.writeText(markdown) | |
| } catch (error) { | |
| console.error('Failed to copy markdown:', error) | |
| } | |
| } | |
| async function copyMarkdownToClipboard() { | |
| const mdUrl = `${router.route.path.replace(/\.html$/, '')}.md` | |
| try { | |
| const response = await fetch(mdUrl) | |
| if (!response.ok) throw new Error(`Failed to fetch: ${response.status}`) | |
| const markdown = await response.text() | |
| await navigator.clipboard.writeText(markdown) | |
| console.log('✓ Markdown copied to clipboard') | |
| } catch (error) { | |
| console.error('Failed to copy markdown:', error) | |
| } | |
| } |
| async function copyMarkdownToClipboard() { | |
| const mdUrl = `https://elysiajs.com${router.route.path.replace(/.html$/g, '')}.md` | |
| try { | |
| const response = await fetch(mdUrl) | |
| const markdown = await response.text() | |
| await navigator.clipboard.writeText(markdown) | |
| } catch (error) { | |
| console.error('Failed to copy markdown:', error) | |
| } | |
| } | |
| async function copyMarkdownToClipboard() { | |
| const mdUrl = `${router.route.path.replace(/\.html$/, '')}.md` | |
| try { | |
| const controller = new AbortController() | |
| const timeoutId = setTimeout(() => controller.abort(), 10000) | |
| const response = await fetch(mdUrl, { signal: controller.signal }) | |
| clearTimeout(timeoutId) | |
| if (!response.ok) throw new Error(`HTTP ${response.status}`) | |
| const markdown = await response.text() | |
| await navigator.clipboard.writeText(markdown) | |
| // TODO: Add toast notification for success | |
| console.log('✓ Markdown copied to clipboard') | |
| } catch (error) { | |
| console.error('Failed to copy markdown:', error) | |
| // TODO: Add toast notification for error | |
| } | |
| } |
Summary
Changes
Why
This makes it easier for users to quickly grab the markdown content for use in AI tools like ChatGPT or Claude without having to navigate to a new tab and manually copy the content.
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.