diff --git a/app/(routes)/(main)/blog/[slug]/page.tsx b/app/(routes)/(main)/blog/[slug]/page.tsx
index d321345..a84d06f 100644
--- a/app/(routes)/(main)/blog/[slug]/page.tsx
+++ b/app/(routes)/(main)/blog/[slug]/page.tsx
@@ -8,6 +8,7 @@ import Image from 'next/image';
import { Badge } from '@/components/ui/badge';
import Markdown from '@/components/markdown';
import TableOfContents from '@/app/_components/_main/table-of-contents';
+import MarkdownCopyListener from '@/app/_components/_main/markdown-copy-listener';
export async function generateMetadata({
params,
@@ -80,6 +81,7 @@ export default async function Page({ params }: { params: { slug: string } }) {
)}
+
{headings.length > 0 && }
>
);
diff --git a/app/_components/_main/markdown-copy-listener.tsx b/app/_components/_main/markdown-copy-listener.tsx
new file mode 100644
index 0000000..88cd824
--- /dev/null
+++ b/app/_components/_main/markdown-copy-listener.tsx
@@ -0,0 +1,29 @@
+'use client'
+import { useEffect } from "react";
+
+export default function MarkdownCopyListener() {
+ useEffect(() => {
+ const copyBtns = document.querySelectorAll('button.copy-code-btn')
+ copyBtns.forEach((btn) => {
+ (btn as HTMLButtonElement).addEventListener('click', () => {
+ const codeBlockContent = btn.parentElement?.nextElementSibling?.textContent
+ if (codeBlockContent) {
+ navigator.clipboard.writeText(codeBlockContent).then(() => {
+ btn.textContent = 'Copied'
+ setTimeout(() => {
+ btn.textContent = 'Copy'
+ }, 2000)
+ })
+ }
+ })
+ })
+
+ return () => {
+ copyBtns.forEach((btn) => {
+ (btn as HTMLButtonElement).removeEventListener('click', () => { })
+ })
+ }
+ }, [])
+
+ return null
+}
diff --git a/components/markdown.tsx b/components/markdown.tsx
index 7176065..9e6759e 100644
--- a/components/markdown.tsx
+++ b/components/markdown.tsx
@@ -43,7 +43,7 @@ const Markdown = ({ markdown }: { markdown: string }) => {
`;
},
code({ text, lang }) {
- return `
${lang}
${text}
`;
+ return `${lang}
${text}
`;
},
link(args) {
const link = marked.Renderer.prototype.link.call(this, args);
@@ -81,7 +81,6 @@ const Markdown = ({ markdown }: { markdown: string }) => {
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(marked.parse(markdown) as string, {
USE_PROFILES: { html: true },
- ADD_ATTR: ['onclick'],
}),
}}
>