Add copy button to blog code blocks - #391
Open
mickqian wants to merge 1 commit into
Open
Conversation
Fenced code blocks in blog posts had no way to copy their contents, so readers had to hand-select the text. That is error-prone for the multi-line launch commands most posts end up showing. Render the button into the static HTML from markdown-it's fence rule rather than attaching it on the client, so it survives `next export`. The button lives in a wrapper around `pre` instead of inside it, because `pre` scrolls horizontally and a button within it would drift off as soon as a long line is scrolled. Copying is handled by a single delegated listener on the article element, since the article is injected as raw HTML and the buttons are not React nodes. Falls back to a selection-based copy where the async clipboard API is unavailable, and keeps the button visible on touch devices, which have no hover state to reveal it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fenced code blocks in blog posts have no way to copy their contents — readers have to hand-select the text, which is error-prone for the multi-line
sglang.launch_servercommands most posts show.This adds a copy button to every fenced code block.
Approach
fencerule, so it is present in thenext exportoutput rather than injected after hydration.pre, not inside it.prehasoverflow-x: scroll, so a button inside would drift out of view as soon as a reader scrolls a long line.dangerouslySetInnerHTML, so the buttons are not React nodes.pre code'stextContent, which is the plain source without the highlight.js markup.Edge cases handled
@media (hover: none)— with hover-only reveal the button would be unreachable there.pregetspadding-rightso the button does not sit on top of the first line.Verification
Ran against
/blog/2026-08-07-hpc-ops-sglangin a real browser:clipboard.writeTextsuccessfully with exactly that block's content (verified 105 chars for block 1, 190 for block 2 — matching each block'stextContentlength).<button type="button">, visible on:focus-visible).npm run buildsucceeds: all 110 blog pages prerender, and the static HTML contains 246 buttons across the 74 posts that have code blocks.Note on scope
This changes the frontend in this repo. Production
www.lmsys.orgis currently served by a separate Next.js App Router project on Vercel (lmsys-web), whose code is not in this repository —src/here was last touched in 2025-12, and thegh-pagesdeploy this repo still builds is no longer in the DNS path. So this PR does not by itself change what readers see on the live site; the same fix needs porting to the App Router project. Filing it here because the code block markup there is the samemarkdown-it-highlightjsoutput (<pre><code class="hljs language-*">), so the selectors and CSS carry over unchanged.🤖 Generated with Claude Code