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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Owner Author

commented Nov 15, 2018

Thanks @okraskaj, I've fixed it.

@reintroducing

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Jan 31, 2019

It works for me, Thanks!

@mwood23

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Apr 26, 2019

This should be in the main docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.