|

How to Add Syntax Highlighting to WordPress Code Blocks: A Practical Guide

Every time I published a tutorial that included code, the default WordPress code block looked flat and unreadable. Plain monospace text on a gray background. No colors, no line numbers, nothing to help a reader scan a snippet and find the line that matters. Nothing beautiful.

I wanted syntax highlighting that didn’t require swapping out the block entirely, especially as I had been using Gutenberg since it first came out. The plugin I previously used for this was deprecated, and most alternatives register their own custom block. That means migrating every existing code block and broken content if you ever deactivate.

This is where WebberZone Code Block Highlighting fits in neatly. I built it as a filter on top of the native core/code block. Your existing posts stay untouched, and if you deactivate the plugin, every block remains a valid standard WordPress code block.

In this guide, I’ll walk you through installing the plugin, choosing between client-side and server-side rendering, picking a theme, and configuring everything from line numbers to copy-to-clipboard.

How to Add Syntax Highlighting to WordPress Code Blocks

Prerequisites

You’ll need WordPress 6.6 or higher and PHP 7.4 or higher. I built the plugin for the block editor using the native block filter APIs, so the Classic Editor is not supported.

That’s it. There are no external services involved, and the plugin makes no outside requests.

Install the Plugin

I kept the installation to the standard flow:

  1. Go to Plugins > Add New in your WordPress admin.
  2. Search for WebberZone Code Block Highlighting.
  3. Click Install Now, then Activate.

Once activated, open any post in the block editor, select a Code block (or add one using /code), and you’ll see a new Code Highlighting panel in the Inspector Controls sidebar.

There is no setup wizard and no shortcodes to learn. The result is a working default the moment you activate it.

Choose a Highlighting Mode

The plugin offers two rendering modes, and I designed them to be interchangeable. Head to Settings > Code Block Highlighting to pick one.

  • Client-side (default) uses Prism.jsOpens in a new window to highlight code in the visitor’s browser. This mode powers the interactive toolbar features, such as copy-to-clipboard and expand/collapse directly.
  • Server-side uses highlight.phpOpens in a new window to pre-render the highlighted markup. No Prism.js or any other JavaScript loads for highlighting. I added this mode in version 1.1.0 for sites that care about Core Web Vitals, run strict content security policies, or want zero-highlighting JavaScript on the page. A lighter JavaScript powers the interactive toolbar.

The best part is that both modes share the same 21 Prism themes and produce visually identical output. Server mode outputs Prism-compatible token classes and loads the same theme CSS, so you can switch between the two at any time without your code blocks changing appearance.

Pick a Theme

From that settings page, choose a Color Scheme. The plugin ships with 21 Prism themes, among them Dracula, GitHub (Light), Night Owl, Nord, One Dark, Solarized Dark, Synthwave ’84, and VS Code Dark+.

The theme applies globally. Per-block theme switching is not currently supported, and I think that’s the right call for visual consistency across a site.

If you need a theme that isn’t bundled, use the wzcbh_color_scheme_css_urlOpens in a new window filter to point at any Prism-compatible CSS file without touching the plugin source.

Set the Language per Block

Select any Code block in the editor and open the Code Highlighting panel in the sidebar. The Language dropdown lists 40 languages, covering PHP, JavaScript, TypeScript, Python, Bash, CSS, SQL, YAML, and plenty more.

Version 1.1.0 also added a Plain Text option. I included it for output logs and configuration fragments that don’t match any grammar: it renders with the theme’s styling but applies no syntax coloring.

Developers can adjust the dropdown with the wzcbh_languagesOpens in a new window filter.

One caveat: adding a language to the filter only changes the UI; the matching Prism grammar must also be available on the frontend.

Enable Line Numbers

In the same sidebar panel, toggle Line Numbers for the current block. You can also choose a custom start line, which I find handy when a snippet continues from an earlier block in the post.

If you want line numbers everywhere, turn on the default on the settings page instead. Then the per-block toggle becomes an override for the occasional exception.

Highlight Specific Lines

When a tutorial says “change line 4”, the reader shouldn’t have to count. Enter a comma-separated list of lines or ranges in the Highlight Lines field, for example:

1,3-5,8

This maps to the data-line attribute consumed by Prism’s line-highlight plugin, and the listed lines render with a visual emphasis on the frontend.

Copy-to-Clipboard and the Toolbar

I enabled a Prism toolbar above each block, controlled globally from the settings page. This setting was missing in the old plugin.

Two options matter here:

  • Copy-to-clipboard adds a button so readers can grab a snippet in one click. For a tutorial-heavy site, this is the feature visitors notice first.
  • Show language label displays the block’s language in the toolbar, giving readers immediate context before they parse a single line.

You can also add a filename or label per block using the Title field in the sidebar. The title appears in the toolbar, so a reader knows exactly which file a snippet belongs to.

Expand/Collapse with Max Height

Long snippets can swallow a post. I added a Max Height option in the block sidebar for exactly this: cap the block at a height in pixels, and an expand/collapse button appears in the toolbar.

Readers who want the full listing can click to expand. Everyone else scrolls past without losing their place. The result is a post that stays readable even with a 200-line code listing in the middle.

Global Defaults and Per-Block Overrides

The Settings > Code Block Highlighting page contains the global defaults: highlighting mode, color scheme, default language, line numbers and start value, word wrap, copy-to-clipboard, language label, and font size.

Every block then inherits those defaults, and the sidebar panel overrides them individually for language, line numbers, start line, word wrap, title, highlighted lines, and max height. Think of it as configure once, override when needed.

This split keeps day-to-day writing fast. I set my defaults on day one and rarely open the settings page since.

Troubleshooting

Highlighting doesn’t appear on a page. I made the plugin only enqueue the theme CSS (and Prism JS in client mode) on pages that contain at least one code block. If you output code through a widget or template part, use the wzcbh_force_load_assetsOpens in a new window filter to load assets everywhere.

Copy-to-clipboard or expand/collapse is missing. These interactive features rely on the client-side mode. Check your rendering mode under Settings > Code Block Highlighting.

A language is missing from the dropdown. Add it with the wzcbh_languagesOpens in a new window filter, and make sure the corresponding Prism grammar is available on the frontend.

Worried about deactivation? Don’t be. Because the plugin extends core/code rather than replacing it, deactivating it removes the highlighting and nothing else. Your content stays valid standard block markup. You might have to “Attempt recovery” code blocks in the backend. Unfortunately, this is a quirk of the block editor.

Wrapping Up

I built WebberZone Code Block Highlighting because I wanted readable code in my own tutorials without having to rebuild years of content around a custom block. The plugin now handles that for every post on this site, in either client-side or server-side mode, with the theme and toolbar setup I described above.

Install it for free from WordPress.org, and your code blocks will look the part on the next post you publish.

Keep on publishing!

Leave a Reply

Your email address will not be published. Required fields are marked *