COPY option for code blocks in Discourse


We have a top secret project we’ve been working on in-house that would really benefit from a COPY TO CLIPBOARD feature for Discourse code blocks.

Others have encountered the problem too:

With a little bit of work we appear to have a great little working model (applied to the labs forum right here) that can be easily applied to other Discourse forums as follows:

  • Go to “Admin” setting page
  • Click on “Customize”, then click on “CSS/HTML”
  • Create a new theme or select an existing one in the left hand column
  • Copy the following code and paste it into </head> section of the selected theme:
<!-- CSS for clipboard -->
<style type="text/css">
    .bd-clipboard {
        display: none;
        float: right;
        height: .5rem;
        position: relative;
        white-space: nowrap;
    .bd-clipboard + pre {
        clear: both;
        margin-top: 0;

    @media (min-width: 768px) {
        .bd-clipboard {
            display: block;

    .btn-clipboard {
        background-color: transparent;
        border-radius: .25rem;
        color: #818a91;
        cursor: pointer;
        display: block;
        font-size: 75%;
        padding: .25rem .5rem;
        position: absolute;
        top: .125rem;
        right: .125rem;
        z-index: 10;
    .btn-clipboard:hover {
        background-color: #027de7;
        color: #ffffff;
    .code-highlight {
        background-color: #f3f3f3;
        margin-bottom: 1rem;
        padding-bottom: .5rem;
    .code-highlight pre {
        margin: 0;
<!-- JavaScript for clipboard -->
<script src=""></script>
<script type="text/discourse-plugin" version="0.8">
        $elem => $('pre', $elem).each(function () {
            // add copy button to code block
            $(this).wrap('<div class="code-highlight"></div>').before('<div class="bd-clipboard"><span class="btn-clipboard">Copy</span></div>')
            // initialise clipboard
            var clipboard = new Clipboard('.btn-clipboard', {
                target: function (trigger) {
                    return trigger.parentNode.nextElementSibling
            // update text of the copy button
            clipboard.on('error', function (e) {
                var modifierKey = /Mac/i.test(navigator.userAgent) ? '\u2318' : 'Ctrl-'
                var fallbackMsg = 'Press ' + modifierKey + 'C to copy'
            clipboard.on('success', function (e) {

    // revert back text of the copy button
    $(document).on('mouseleave', '.btn-clipboard', function () {

Discourse uses ember.js for internal navigation, so the DOM will only be ready once. I have tied up the clipboard function with ember.js via Discourse APIs, so the code now runs when the content of a post is cooked instead of on DOM ready.


just a small note if you noticed already then my bad.
The copy button seem to be on top of the scroll bar. I can’t click the up arrow without copying :slight_smile:
edit: I just tried again and I can very narrowly click the up arrow.