WordPress Advanced Code Block Toolbar Source Code
This lightweight, zero-plugin solution upgrades default WordPress <pre><code> and Gutenberg Code Blocks with a macOS-inspired header bar featuring Auto Language Detection, One-Click Copy, Word-Wrap Toggle, Download as File, Fullscreen Mode, and Auto-Collapse for Long Snippets.
1. CSS (nx-code-toolbar.css)
Add this to your theme’s style.css, Additional CSS customizer, or enqueue it as a stylesheet:
/* ==========================================================================
NitroX WordPress Code Block Wrapper & Toolbar
========================================================================== */
:root {
--nx-code-bg: #090d16;
--nx-bar-bg: #131b2e;
--nx-border: #1e293b;
--nx-text: #e2e8f0;
--nx-muted: #94a3b8;
--nx-accent: #10b981;
--nx-accent-blue: #3b82f6;
--nx-radius: 12px;
}
.nx-code-wrapper {
position: relative;
margin: 1.75rem 0;
background-color: var(--nx-code-bg);
border: 1px solid var(--nx-border);
border-radius: var(--nx-radius);
overflow: hidden;
box-shadow: 0 12px 24px -8px rgba(0, 0, 0, 0.45);
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Courier New", monospace;
}
/* Fullscreen Mode State */
.nx-code-wrapper.is-fullscreen {
position: fixed;
inset: 0;
z-index: 99999;
margin: 0;
border-radius: 0;
display: flex;
flex-direction: column;
}
.nx-code-wrapper.is-fullscreen pre.wp-block-code,
.nx-code-wrapper.is-fullscreen pre {
flex: 1;
max-height: none !important;
}
/* ==========================================================================
Top Header Bar (macOS Dots, Language Tag & Action Buttons)
========================================================================== */
.nx-code-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.6rem 1rem;
background-color: var(--nx-bar-bg);
border-bottom: 1px solid var(--nx-border);
user-select: none;
gap: 0.75rem;
flex-wrap: wrap;
}
.nx-toolbar-left {
display: flex;
align-items: center;
gap: 0.75rem;
}
.nx-window-dots {
display: inline-flex;
gap: 6px;
}
.nx-window-dots span {
width: 10px;
height: 10px;
border-radius: 50%;
}
.nx-window-dots span:nth-child(1) { background-color: #ef4444; }
.nx-window-dots span:nth-child(2) { background-color: #f59e0b; }
.nx-window-dots span:nth-child(3) { background-color: #10b981; }
.nx-lang-badge {
font-size: 0.72rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--nx-accent);
background: rgba(16, 185, 129, 0.12);
padding: 0.2rem 0.6rem;
border-radius: 6px;
}
/* Action Buttons Group */
.nx-toolbar-actions {
display: flex;
align-items: center;
gap: 0.4rem;
}
.nx-tool-btn {
display: inline-flex;
align-items: center;
gap: 0.35rem;
background-color: rgba(255, 255, 255, 0.04);
color: var(--nx-muted);
border: 1px solid var(--nx-border);
border-radius: 6px;
padding: 0.32rem 0.65rem;
font-size: 0.75rem;
font-weight: 600;
font-family: system-ui, -apple-system, sans-serif;
cursor: pointer;
transition: all 0.2s ease;
line-height: 1.2;
}
.nx-tool-btn:hover {
color: #ffffff;
border-color: #334155;
background-color: rgba(255, 255, 255, 0.08);
}
.nx-tool-btn.active {
color: var(--nx-accent-blue);
border-color: rgba(59, 130, 246, 0.4);
background-color: rgba(59, 130, 246, 0.12);
}
.nx-tool-btn.nx-copy-btn {
background-color: rgba(16, 185, 129, 0.12);
color: var(--nx-accent);
border-color: rgba(16, 185, 129, 0.3);
}
.nx-tool-btn.nx-copy-btn:hover,
.nx-tool-btn.nx-copy-btn.copied {
background-color: var(--nx-accent);
color: #05080e;
border-color: var(--nx-accent);
}
.nx-tool-btn svg {
width: 14px;
height: 14px;
stroke: currentColor;
stroke-width: 2;
fill: none;
flex-shrink: 0;
}
/* ==========================================================================
Code Body, Line Wrapping & Collapsible Long Code
========================================================================== */
.nx-code-wrapper pre.wp-block-code,
.nx-code-wrapper pre {
margin: 0 !important;
padding: 1.25rem !important;
background: transparent !important;
border: none !important;
border-radius: 0 !important;
color: var(--nx-text);
font-size: 0.88rem;
line-height: 1.65;
overflow-x: auto;
white-space: pre;
tab-size: 2;
}
/* Word Wrap Enabled State */
.nx-code-wrapper.is-wrapped pre,
.nx-code-wrapper.is-wrapped pre code {
white-space: pre-wrap !important;
word-break: break-word !important;
overflow-x: hidden !important;
}
/* Auto-Collapsed State for Long Code Blocks (> 380px) */
.nx-code-wrapper.is-collapsible:not(.is-expanded):not(.is-fullscreen) pre {
max-height: 360px;
overflow-y: hidden;
}
.nx-expand-bar {
display: none;
justify-content: center;
align-items: flex-end;
padding: 2.5rem 1rem 0.75rem;
background: linear-gradient(to bottom, rgba(9, 13, 22, 0), rgba(9, 13, 22, 0.96) 65%);
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.nx-code-wrapper.is-collapsible:not(.is-fullscreen) .nx-expand-bar {
display: flex;
}
.nx-code-wrapper.is-expanded .nx-expand-bar {
position: static;
padding: 0.65rem 1rem;
background: var(--nx-bar-bg);
border-top: 1px solid var(--nx-border);
}
.nx-expand-btn {
background-color: var(--nx-bar-bg);
color: var(--nx-text);
border: 1px solid var(--nx-border);
border-radius: 999px;
padding: 0.35rem 1rem;
font-size: 0.76rem;
font-weight: 700;
font-family: system-ui, -apple-system, sans-serif;
cursor: pointer;
transition: border-color 0.2s ease, color 0.2s ease;
}
.nx-expand-btn:hover {
border-color: var(--nx-accent);
color: var(--nx-accent);
}
@media (max-width: 600px) {
.nx-btn-label {
display: none; /* Keep icons compact on small mobile screens */
}
.nx-copy-btn .nx-btn-label {
display: inline; /* Always show "Copy" text */
}
}
2. JavaScript (nx-code-toolbar.js)
This script automatically detects all WordPress <pre> blocks, identifies the coding language, builds the interactive toolbar, and wires up every button:
document.addEventListener('DOMContentLoaded', () => {
const codeBlocks = document.querySelectorAll('pre.wp-block-code, article pre, .entry-content pre');
if (!codeBlocks.length) return;
// Map detected languages to clean labels and file extensions
const LANG_MAP = {
html: { label: 'HTML', ext: 'html' },
xml: { label: 'HTML', ext: 'html' },
css: { label: 'CSS', ext: 'css' },
scss: { label: 'SCSS', ext: 'scss' },
js: { label: 'JavaScript', ext: 'js' },
javascript: { label: 'JavaScript', ext: 'js' },
php: { label: 'PHP', ext: 'php' },
python: { label: 'Python', ext: 'py' },
py: { label: 'Python', ext: 'py' },
sql: { label: 'SQL', ext: 'sql' },
json: { label: 'JSON', ext: 'json' },
bash: { label: 'Bash', ext: 'sh' },
shell: { label: 'Shell', ext: 'sh' }
};
// Auto-detect language from classes or code syntax
const detectLanguage = (preEl, codeEl) => {
const classStr = `${preEl.className} ${codeEl ? codeEl.className : ''}`.toLowerCase();
const match = classStr.match(/(?:lang|language)-([a-z0-9]+)/);
if (match && LANG_MAP[match[1]]) {
return LANG_MAP[match[1]];
}
const raw = (codeEl ? codeEl.textContent : preEl.textContent).trim();
if (/^(<!DOCTYPE html|<html|<div|<section|<header|<form)/i.test(raw)) return LANG_MAP.html;
if (/^(<\?php|namespace\s|add_action\()/i.test(raw)) return LANG_MAP.php;
if (/^(:root|\.[a-z0-9_-]+\s*\{|@media)/i.test(raw)) return LANG_MAP.css;
if (/(document\.addEventListener|const\s+\w+\s*=|function\s+\w+)/.test(raw)) return LANG_MAP.js;
return { label: 'Code', ext: 'txt' };
};
// Safe Clipboard Copy Helper (Supports HTTPS & Localhost/HTTP Fallback)
const copyToClipboard = async (text) => {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(text);
} else {
const tempInput = document.createElement('textarea');
tempInput.value = text;
tempInput.style.position = 'fixed';
tempInput.style.opacity = '0';
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand('copy');
document.body.removeChild(tempInput);
}
};
codeBlocks.forEach((pre, index) => {
// Prevent double-initialization
if (pre.parentElement.classList.contains('nx-code-wrapper')) return;
const codeEl = pre.querySelector('code') || pre;
const langInfo = detectLanguage(pre, codeEl);
// 1. Create Wrapper
const wrapper = document.createElement('div');
wrapper.className = 'nx-code-wrapper';
pre.parentNode.insertBefore(wrapper, pre);
// 2. Create Toolbar HTML
const toolbar = document.createElement('div');
toolbar.className = 'nx-code-toolbar';
toolbar.innerHTML = `
<div class="nx-toolbar-left">
<div class="nx-window-dots" aria-hidden="true">
<span></span><span></span><span></span>
</div>
<span class="nx-lang-badge">${langInfo.label}</span>
</div>
<div class="nx-toolbar-actions">
<button type="button" class="nx-tool-btn nx-wrap-btn" title="Toggle Word Wrap" aria-label="Toggle Word Wrap">
<svg viewBox="0 0 24 24"><path d="M3 6h18M3 12h15a3 3 0 1 1 0 6h-4m0 0 2-2m-2 2 2 2M3 18h7" stroke-linecap="round" stroke-linejoin="round"/></svg>
<span class="nx-btn-label">Wrap</span>
</button>
<button type="button" class="nx-tool-btn nx-dl-btn" title="Download Code File" aria-label="Download Code">
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" stroke-linecap="round" stroke-linejoin="round"/></svg>
<span class="nx-btn-label">Download</span>
</button>
<button type="button" class="nx-tool-btn nx-fs-btn" title="Toggle Fullscreen" aria-label="Toggle Fullscreen">
<svg viewBox="0 0 24 24"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" stroke-linecap="round" stroke-linejoin="round"/></svg>
<span class="nx-btn-label">Expand</span>
</button>
<button type="button" class="nx-tool-btn nx-copy-btn" title="Copy Code" aria-label="Copy Code">
<svg class="nx-icon-copy" viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<span class="nx-btn-label">Copy</span>
</button>
</div>
`;
wrapper.appendChild(toolbar);
wrapper.appendChild(pre);
// 3. Auto-Collapse Tall Code Blocks (> 380px height)
if (pre.scrollHeight > 380) {
wrapper.classList.add('is-collapsible');
const expandBar = document.createElement('div');
expandBar.className = 'nx-expand-bar';
expandBar.innerHTML = `<button type="button" class="nx-expand-btn">Show Full Code (${pre.textContent.split('\n').length} lines)</button>`;
wrapper.appendChild(expandBar);
const expandBtn = expandBar.querySelector('.nx-expand-btn');
expandBtn.addEventListener('click', () => {
const isExpanded = wrapper.classList.toggle('is-expanded');
expandBtn.textContent = isExpanded
? 'Collapse Code'
: `Show Full Code (${pre.textContent.split('\n').length} lines)`;
});
}
// 4. Button Event Listeners
const wrapBtn = toolbar.querySelector('.nx-wrap-btn');
const dlBtn = toolbar.querySelector('.nx-dl-btn');
const fsBtn = toolbar.querySelector('.nx-fs-btn');
const copyBtn = toolbar.querySelector('.nx-copy-btn');
// Word Wrap Action
wrapBtn.addEventListener('click', () => {
const wrapped = wrapper.classList.toggle('is-wrapped');
wrapBtn.classList.toggle('active', wrapped);
});
// Download Snippet Action
dlBtn.addEventListener('click', () => {
const rawCode = codeEl.textContent;
const blob = new Blob([rawCode], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `nitrox-snippet-${index + 1}.${langInfo.ext}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
});
// Fullscreen Action
fsBtn.addEventListener('click', () => {
const isFs = wrapper.classList.toggle('is-fullscreen');
fsBtn.classList.toggle('active', isFs);
fsBtn.querySelector('.nx-btn-label').textContent = isFs ? 'Exit' : 'Expand';
document.body.style.overflow = isFs ? 'hidden' : '';
});
// Copy Code Action
copyBtn.addEventListener('click', async () => {
try {
await copyToClipboard(codeEl.textContent);
const label = copyBtn.querySelector('.nx-btn-label');
copyBtn.classList.add('copied');
label.textContent = 'Copied!';
setTimeout(() => {
copyBtn.classList.remove('copied');
label.textContent = 'Copy';
}, 2000);
} catch (err) {
console.error('Copy failed', err);
}
});
});
// Escape Key Exits Fullscreen Code View
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
const activeFs = document.querySelector('.nx-code-wrapper.is-fullscreen');
if (activeFs) {
activeFs.classList.remove('is-fullscreen');
const fsBtn = activeFs.querySelector('.nx-fs-btn');
if (fsBtn) {
fsBtn.classList.remove('active');
fsBtn.querySelector('.nx-btn-label').textContent = 'Expand';
}
document.body.style.overflow = '';
}
}
});
});
3. WordPress functions.php Enqueue Snippet
To load these assets cleanly inside your WordPress theme (only on single posts or pages that actually contain a <pre> block), add this snippet to your theme’s functions.php file:
<?php
/**
* Enqueue NitroX Code Block Toolbar Assets Conditionally
*/
function nitrox_enqueue_code_toolbar() {
if ( is_singular() ) {
global $post;
// Only load CSS & JS if the post contains a code block (<pre>)
if ( isset( $post->post_content ) && strpos( $post->post_content, '<pre' ) !== false ) {
wp_enqueue_style(
'nitrox-code-toolbar',
get_stylesheet_directory_uri() . '/assets/css/nx-code-toolbar.css',
array(),
'1.0.0'
);
wp_enqueue_script(
'nitrox-code-toolbar',
get_stylesheet_directory_uri() . '/assets/js/nx-code-toolbar.js',
array(),
'1.0.0',
true // Load in footer
);
}
}
}
add_action( 'wp_enqueue_scripts', 'nitrox_enqueue_code_toolbar' );
How to Add a Copy Button and Developer Toolbar to WordPress Code Blocks (Without Plugins)
If you run a programming blog, tutorial site, or developer documentation hub on WordPress, the default Gutenberg Code Block (<pre class="wp-block-code">) leaves a lot to be desired. Out of the box, WordPress renders plain text inside a static box without a copy button, language indicator, word-wrap control, or height limit—forcing readers to manually drag-select hundreds of lines of code on mobile and desktop screens.
While third-party syntax highlighting plugins exist, many load bloated stylesheets and scripts on every page of your site, hurting Core Web Vitals. In this guide, you will learn how to install a fast, zero-dependency Developer Code Toolbar in WordPress that adds five essential actions to every code snippet automatically.
Key Features Included in This Toolbar
- One-Click Copy to Clipboard: Copies the raw code inside
<code>using the modernnavigator.clipboardAPI (with an automatic fallback for local testing environments) and triggers a 2-second"Copied!"visual confirmation. - Smart Language Detection & Custom Overrides: Automatically inspects the code block for language classes (
language-html,language-js,language-php) or analyzes the first lines of code to display an accurate language badge. - Word-Wrap Toggle: Long single-line strings (like SVG paths or terminal commands) often cause horizontal scrolling. Clicking Wrap toggles
white-space: pre-wrapso readers can inspect long lines without scrolling sideways. - Instant File Download: Converts the code block’s contents into a native browser
Bloband downloads it with the matching file extension (.html,.css,.js,.php, or.py). - Fullscreen Mode & Auto-Collapse: Code blocks taller than
380pxare automatically collapsed behind a sleek gradient"Show Full Code"bar so long source files never overwhelm your article layout, while the Expand button lets readers inspect complex scripts in a distraction-free fullscreen modal.
How to Set a Specific Language Badge in the WordPress Block Editor
Although our JavaScript engine automatically recognizes common HTML, CSS, JavaScript, and PHP syntax, you can also explicitly tell the toolbar which language badge and download extension to use right inside the WordPress Gutenberg editor:
- Click on any Code Block inside your WordPress post editor.
- Open the right-hand Block Settings sidebar and scroll down to the Advanced tab.
- In the Additional CSS class(es) input field, type
language-html,language-css,language-js,language-php,language-python, orlanguage-sql. - Update your post. The toolbar will immediately display that exact language badge and use its matching file extension when visitors click Download.
Why Conditional Loading Matters for WordPress Speed
Notice how our functions.php snippet checks strpos( $post->post_content, '<pre' ) !== false before enqueuing the CSS and JavaScript files. This ensures that your homepage, archive pages, contact page, and non-technical blog posts load zero extra bytes of CSS or JS—keeping your WordPress site blazingly fast while giving developer articles a premium interactive experience.
