Copy to clipboard from code highlight context

There are interesting suggestions on how to add copy to clipboard for code in a syntax highlight context, for example, Hugo: Add Copy-to-Clipboard Button to Code Blocks with Vanilla JS - aaronluna.dev, and
How to Add Copy to Clipboard Buttons to Code Blocks in Hugo.

I’ve tried both, but could not get it to work with the latest version of hugo (v0.125.4) under
Ubuntu Linux. I tested with a couple of example themes.

I insert the JavaScript code into static/js/copy-code-button.js, and the CSS code into
assets/_custom.scss (also tried assets/custom.scss). The JavaScript code is inserted
at the end of layouts/_defaults/baseof.html. By using show source it appears the
JavaScript is inserted where it is needed, and the Copy button appears, but when I click
on the Copy button nothing happens, and the browser inspect viewer shows that an
error results: Uncaught TypeError: cannot read properties of null (reading innerText).

If instead of using the reference to innerText I simply assign an arbitrary text
string to codeToCopy there are no errors, so the problem seems to be caused
by the selector :last-child > .chroma > code.

Any tips? Is there currently a standard way to do this using Hugo?

Thanks!

That’s actually not a Hugo issue, I think. The JS code tries to read the innerText of an element that does not exist. Have a look at your HTML DOM and see what selector you can use to address the code block.

1 Like

Thanks. I found a work-around: add to the toml file pygmentsUseClasses = true.

This has the effect of placing line numbers and code in separate table columns,
so the code selector works. The use of ‘pygments’ here is confusing, because
Hugo uses chroma, not pygments (historical artifact?).

Setting pygmentsUseClasses removes color. The work-around is to use
hugo new chromastyles --style='monokai' > chroma.css, then append
chroma.css to assets/css/main.css. The last bit is missing from the
documentation (the css files must be included somewhere in layouts,
and main.css is a commonly included file).

This is a simple example using Hugo’s default syntax highlighter (Chroma) in conjunction with clipboard.js.

git clone --single-branch -b hugo-forum-topic-49633 https://github.com/jmooring/hugo-testing hugo-forum-topic-49633
cd hugo-forum-topic-49633
npm ci
hugo server

This works with code blocks that have:

  • No line numbers
  • Line numbers inline
  • Line numbers in a table cell

Files of interest

  • assets/js/main.js
  • assets/sass/main.scss (lines 60-68)
  • layouts/_default/baseof.html (lines 8-9)
  • layouts/_default/_markup/render-codeblock.html
  • layouts/partials/head/*

1 Like

Thanks!

It seems to me that a natural place for this functionality would be as an additional option for the highlight shortcode, like includeCopyButton="true". This would eliminate the need to mix and match different solutions that have been proposed, sometimes with conflicting objectives.

A fenced code block is portable to other Markdown readers/writers (e.g., Obsidian, Typora, GitHub, GitLab, etc.). A shortcode is not portable… it only has meaning to Hugo.

And if you’re going to use a fenced code block, you’ll need…

  • A code block render hook
  • JavaScript
  • CSS

…which is why I provided the example above.

1 Like

Can you provide pointers on how to use ~/node_modules with Hugo? I got as far as npm install clipboard, but when I run hugo server with all of the files copied into the hugo-book theme, it looks like it is not finding the clipboard module (no constructor). Just copying ~/node_modules to the root of the Hugo project doesn’t help, nor does npm install.

Your example has a minimal hugo.toml, not mounting anything, and not configuring [markup.highlight], so it is not clear how this works.

This raises a more general question, how to incorporate changes like this into an existing theme without introducing conflicts? For example, the theme might already have layouts/partials/head/*, or may have CSS rules that conflict with the ones
in this example.

I see that the Hugo documentation supports the copy button (see docs on
partialCached), so adding a copy button is a commonly encountered and solved problem. Does the Hugo documentation use a book-like theme with copy button support?

Thanks!

The Hugo documentation site uses a custom theme specifically for that site, and it uses clipboard.js with a somewhat similar setup to the example I provided.

Regarding your other questions, you need to have some JS background to understand how this works. If you can’t figure out how this works from the example that I provided, you might consider reaching out to theme author for suggestions.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.