Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to add the "Copy" button to code blocks in Docusaurus

Adding "Copy" (to Clipboard) Button

If you would like to add a button to your fenced code blocks so that users may copy the code, you can do so in Docusaurus. You will have to add some code to your Docusaurus project, as seen below.

Under static/js, create a file called code-block-buttons.js with the following:

// Turn off ESLint for this file because it's sent down to users as-is.
/* eslint-disable */
window.addEventListener('load', function() {
  function button(label, ariaLabel, icon, className) {
    const btn = document.createElement('button');
    btn.classList.add('btnIcon', className);
    btn.setAttribute('type', 'button');
    btn.setAttribute('aria-label', ariaLabel);
    btn.innerHTML =
      '<div class="btnIcon__body">' +
      icon +
      '<strong class="btnIcon__label">' +
      label +
      '</strong>' +
      '</div>';
    return btn;
  }

  function addButtons(codeBlockSelector, btn) {
    document.querySelectorAll(codeBlockSelector).forEach(function(code) {
      code.parentNode.appendChild(btn.cloneNode(true));
    });
  }

  const copyIcon =
    '<svg width="12" height="12" viewBox="340 364 14 15" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M342 375.974h4v.998h-4v-.998zm5-5.987h-5v.998h5v-.998zm2 2.994v-1.995l-3 2.993 3 2.994v-1.996h5v-1.995h-5zm-4.5-.997H342v.998h2.5v-.997zm-2.5 2.993h2.5v-.998H342v.998zm9 .998h1v1.996c-.016.28-.11.514-.297.702-.187.187-.422.28-.703.296h-10c-.547 0-1-.452-1-.998v-10.976c0-.546.453-.998 1-.998h3c0-1.107.89-1.996 2-1.996 1.11 0 2 .89 2 1.996h3c.547 0 1 .452 1 .998v4.99h-1v-2.995h-10v8.98h10v-1.996zm-9-7.983h8c0-.544-.453-.996-1-.996h-1c-.547 0-1-.453-1-.998 0-.546-.453-.998-1-.998-.547 0-1 .452-1 .998 0 .545-.453.998-1 .998h-1c-.547 0-1 .452-1 .997z" fill-rule="evenodd"/></svg>';

  addButtons(
    '.hljs',
    button('Copy', 'Copy code to clipboard', copyIcon, 'btnClipboard'),
  );

  const clipboard = new ClipboardJS('.btnClipboard', {
    target: function(trigger) {
      return trigger.parentNode.querySelector('code');
    },
  });

  clipboard.on('success', function(event) {
    event.clearSelection();
    const textEl = event.trigger.querySelector('.btnIcon__label');
    textEl.textContent = 'Copied';
    setTimeout(function() {
      textEl.textContent = 'Copy';
    }, 2000);
  });
});

Under static/css, create a file called code-block-buttons.css and add the following:

/* "Copy" code block button */
pre {
  position: relative;
}

pre .btnIcon {
  position: absolute;
  top: 4px;
  z-index: 2;
  cursor: pointer;
  border: 1px solid transparent;
  padding: 0;
  color: #fff;
  background-color: transparent;
  height: 30px;
  transition: all .25s ease-out;
}

pre .btnIcon:hover {
  text-decoration: none;
}

.btnIcon__body {
  align-items: center;
  display: flex;
}

.btnIcon svg {
  fill: currentColor;
  margin-right: .4em;
}

.btnIcon__label {
  font-size: 11px;
}

.btnClipboard {
  right: 10px;
}

Add the following to siteConfig.js:

scripts: [
  'https://buttons.github.io/buttons.js',
  'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js',
  '/js/code-block-buttons.js',
],
stylesheets: ['/css/code-block-buttons.css']

Your "Copy" to clipboard buttons should now appear at the upper right of every fenced code block.

@okraskaj
Copy link

okraskaj commented Nov 5, 2018

File names in the instructions don't match the ones in siteConfig text- it should be either code-block-buttons or code-blocks-buttons.

@yangshun
Copy link
Author

yangshun commented Nov 15, 2018

Thanks @okraskaj, I've fixed it.

@reintroducing
Copy link

reintroducing commented Nov 29, 2018

it seems that adding stylesheets actually doesnt work, you get a 404 trying to load the CSS. the CSS from that file, however, does end up included in the final generated main.css, so just removing stylesheets entry from the siteConfig.js would be the right thing to do here.

@cmutagorama
Copy link

cmutagorama commented Jan 31, 2019

It works for me, Thanks!

@mwood23
Copy link

mwood23 commented Apr 7, 2019

For anyone that's deploying to Github pages or using a baseUrl it won't work as is. The path of the JS script needs to be the same. So you need to do something like this...

// ...
baseUrl: '/your/base/url/'
  scripts: [
    'https://buttons.github.io/buttons.js',
    'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js',
    '/your/base/url/js/code-block-buttons.js',
  ],
// ...

It also breaks if you make the path with a template string. Hope this helps someone!

@bettiolo
Copy link

bettiolo commented Apr 26, 2019

This should be in the main docs

@CGick
Copy link

CGick commented Jul 23, 2019

Can this button be togglable on a per code block basis?

@joshlarsen
Copy link

joshlarsen commented Jan 29, 2020

it seems that adding stylesheets actually doesnt work, you get a 404 trying to load the CSS. the CSS from that file, however, does end up included in the final generated main.css, so just removing stylesheets entry from the siteConfig.js would be the right thing to do here.

@reintroducing is right, adding stylesheets: ['/css/code-block-buttons.css'] is not needed, and in fact results in a 404.

Maybe someone should update the main docs instead of relying this outdated, standalone set of instructions.

@Zenahr
Copy link

Zenahr commented Jun 22, 2020

Agreed. This should be part of the main docs.

@yangshun
Copy link
Author

yangshun commented Aug 3, 2021

Please upgrade to Docusaurus v2 instead! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment