Hi all!
I’d like to know if anyone’s figured out how to create a code cell you can copy & paste from in webflow.
The code would NOT be executable. Rather, we want a user to click a small icon which copies the code into their clipboard.
You can see an example of what we’re looking for in the the docs of this page:
(The box up top).
Have been searching for a while without luck. Any help would be appreciated.
1 Like
Hey @Justin_Tenuto - try this:
Embed this where you want your code block to appear:
<div class="CodeSnippet">
<button class="CopyButton"><i class="far fa-copy"></i> Copy Code</button>
<div class="codeCopied">
Copied to clipboard!
</div>
<pre class="snippet"><code class="json" >
const userAction = async () => {
const response = await fetch('http://example.com/movies.json', {
method: 'POST',
body: myBody, // string or object
headers: {
'Content-Type': 'application/json'
}
});
const myJson = await response.json(); //extract JSON from the http response
// do something with myJson
}
</code>
</pre>
</div>
Embed this in the sitewide/page level head tag:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" />
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/styles/night-owl.min.css" integrity="sha512-xYwrX34LRktCfb+3WW0FtJf6qEc2tcJet152No8epFPBoM4qNaaVk5xdfCYI0Ns0H2jD0Isc3VoShSMv6zzpPA==" crossorigin="anonymous" />
<script>hljs.highlightAll();</script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.CodeSnippet {
max-width: 800px;
width: 100%;
margin: 0px auto;
min-width: 300px;
position: relative;
}
.snippet {
font-size: 16px;
}
.CopyButton {
position: absolute;
top: 15px;
right: 15px;
background-color: #3e66fc;
border: none;
outline: none;
color: white;
padding: 9px 20px;
border-radius: 5px;
cursor: pointer;
font-family: monospace;
font-weight: 500;
transition: all .2s ease;
}
.CopyButton:hover {
background-color: #3B5CF1;
}
.codeCopied {
background-color: #2D53F5;
padding: 9px 15px;
color: white;
position: absolute;
right: 15px;
bottom: -10px;
font-family: monospace;
display: inline-block;
border-radius: 5px;
transition: all .3s ease;
opacity: 0;
}
.codeCopied-active {
bottom: 55px;
opacity: 1;
}
.fa-copy {
pointer-events: none;
}
/* width */
.CodeSnippet ::-webkit-scrollbar {
width: 8px;
}
/* Track */
.CodeSnippet ::-webkit-scrollbar-track {
background: #071725;
}
.CodeSnippet /* Handle */
::-webkit-scrollbar-thumb {
background: #2D53F5;
}
/* Handle on hover */
.CodeSnippet ::-webkit-scrollbar-thumb:hover {
background: #3B5CF1;
}
</style>
Finally, embed this in the sitewide/page level body tag:
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
<script>
new ClipboardJS('.CopyButton', {
target: function(trigger) {
return trigger.nextElementSibling.nextElementSibling.firstChild;
}
});
window.addEventListener('click', (e)=>{
if(e.target.classList.contains("CopyButton")){
e.target.nextElementSibling.classList.add("codeCopied-active");
if (window.getSelection) {window.getSelection().removeAllRanges();}
else if (document.selection) {document.selection.empty();}
setTimeout(()=>{
e.target.nextElementSibling.classList.remove("codeCopied-active");
},4000)
}
});
</script>
Let me know if this gives you any issues!
Hi, i don’t quite understand the first embed
say i want implemt a copy code button for this block code how to go about it?
I put this global script to my pages to make this work.
<script>
document.addEventListener('DOMContentLoaded', function() {
function addCopyButton(preElement) {
const copyButtonHtml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="24" height="24" fill="currentColor">
<path d="M208 0H332.1c12.7 0 24.9 5.1 33.9 14.1l67.9 67.9c9 9 14.1 21.2 14.1 33.9V336c0 26.5-21.5 48-48 48H208c-26.5 0-48-21.5-48-48V48c0-26.5 21.5-48 48-48zM48 128h80v64H64V448H256V416h64v48c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48z"/>
</svg>`;
// Create the button element
const button = document.createElement('button');
button.innerHTML = copyButtonHtml;
button.style.position = 'absolute';
button.style.top = '8px';
button.style.right = '8px';
button.style.background = 'none';
button.style.border = 'none';
button.style.cursor = 'pointer';
button.style.padding = '0';
button.style.outline = 'none';
button.style.color = 'grey';
// Wrap the <pre> element in a relative positioned container
const wrapper = document.createElement('div');
wrapper.style.position = 'relative';
wrapper.style.display = 'inline-block';
wrapper.style.width = "100%";
preElement.parentNode.insertBefore(wrapper, preElement);
wrapper.appendChild(preElement);
wrapper.appendChild(button);
// Add click event listener to the button
button.addEventListener('click', function() {
const codeText = preElement.innerText;
navigator.clipboard.writeText(codeText).then(() => {
button.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="24" height="24" fill="currentColor">
<path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/>
</svg>`;
setTimeout(() => {
button.innerHTML = copyButtonHtml;
}, 2000);
}).catch(err => {
console.error('Failed to copy: ', err);
});
});
}
// Find all <pre> elements on the page and add the copy button to each
document.querySelectorAll('pre').forEach(preElement => {
addCopyButton(preElement);
});
});
</script>