React-Markdown - How To Create a Copy Code Button

Full-Stack Development

Markdown is the markup language of choice for tech-savvy bloggers and publishing code samples is commonplace. When creating tutorials (such as this one), it's nice to have a quick way to copy a code block to the clipboard, instead of having to drag-select the code.

This tutorial will use two React libraries: react-markdown and react-syntax-highlighter.

We start with a component called postBody. This is responsible for rendering our markdown as HTML:

import ReactMarkdown from 'react-markdown'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { a11yDark } from 'react-syntax-highlighter/dist/cjs/styles/prism' import CodeCopyBtn from './codeCopyBtn'; export default function PostBody({ content }) { // Add the CodeCopyBtn component to our PRE element const Pre = ({ children }) => <pre className="blog-pre"> <CodeCopyBtn>{children}</CodeCopyBtn> {children} </pre> return ( <ReactMarkdown className='post-markdown' linkTarget='_blank' rehypePlugins={[rehypeRaw]} remarkPlugins={[remarkGfm]} components={{ pre: Pre, code({ node, inline, className = "blog-code", children, ...props }) { const match = /language-(\w+)/.exec(className || '') return !inline && match ? ( <SyntaxHighlighter style={a11yDark} language={match[1]} PreTag="div" {...props} > {String(children).replace(/\n$/, '')} </SyntaxHighlighter> ) : ( <code className={className} {...props}> {children} </code> ) } }} > {content} </ReactMarkdown> ) }

And then we'll create a component called codeCopyBtn:

import React from "react"; export default function CodeCopyBtn({ children }) { const [copyOk, setCopyOk] = React.useState(false); const iconColor = copyOk ? '#0af20a' : '#ddd'; const icon = copyOk ? 'fa-check-square' : 'fa-copy'; const handleClick = (e) => { navigator.clipboard.writeText(children[0].props.children[0]); console.log(children) setCopyOk(true); setTimeout(() => { setCopyOk(false); }, 500); } return ( <div className="code-copy-btn"> <i className={`fas ${icon}`} onClick={handleClick} style={{color: iconColor}} /> </div> ) }

And here's the CSS:

.blog-pre { margin-bottom: 3em !important; -webkit-box-shadow: -10px 0px 13px -7px #000000, 10px 0px 13px -7px #000000, 35px -23px 2px -16px rgba(0, 0, 0, 0); box-shadow: -10px 0px 13px -7px #000000, 10px 0px 13px -7px #000000, 35px -23px 2px -16px rgba(0, 0, 0, 0); position: relative; } .code-copy-btn { color: white; position: absolute; right: 10px; top: -2px; font-size: 1.5em; cursor: pointer; transition: all 0.3s ease-in-out; } .code-copy-btn:hover { transform: scale(1.1); opacity: 0.9; }

I hope you found this tutorial useful. Happy coding!

For more greate information, please Visit our Blog.

Read More Posts

We Welcome Your Likes!