Adding syntax highlighting to Ghost with highlight.js
2 min read

Adding syntax highlighting to Ghost with highlight.js

For sexy code snippets

After my recent relooking, I finally took the time to add syntax highlighting for code snippets.

While Ghost doesn't support code syntax highlighting out the box, it lay down the groundwork for it.

The old Ghost editor was using markdown, so a language could be specified for a code snippet like:

```python
print("nice snippet")
```

The new editor, while not using markdown, still has this feature:

This does do much, besides adding a specific class to the generated HTML code.

Our snippet above is rendered like this:

</p>
    <pre>
        <code class="language-markdown">
        ```python
        print("nice snippet")
        ```
        </code>
    </pre>
<p>

We can take advantage of this to parse the snippets according to some language grammar on the client-side and apply custom styles.

Setting up highlight.js

I would have loved if Ghost handled all the syntax highlighting natively in the rendering engine, but it doesn't. Thus, we have to add some client-side code to do the job.

For the record, there is an official tutorial on the subject that uses prism.js.

I decided to use highlight.js.

Setting up highlight.js is surprisingly easy. Two files are needed: the JS library and a tiny CSS theme file.

These two files can be found cdnsjs.com. When copying the code snippet, make sure you keep the SRI property.

For version 10.0.2 with the default theme, we would have:

<link rel="stylesheet"
	href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/styles/default.min.css" 
	integrity="sha256-48w2xk74a+0hWSZT2qyC/X5MNkwyyDRDNqoT99v1LJA=" 
	crossorigin="anonymous" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/highlight.min.js" 
	integrity="sha256-xBWd+VDTBasaTja2bfaCX4aA2H18UxRsjRFkK3rgfkI=" 
	crossorigin="anonymous">
</script>

<script>hljs.initHighlightingOnLoad();</script>

The simplest and easiest way of integrating it into a Ghost website would be trough code injection:

That's it!

Since I maintain my own theme, I didn't use code injection. I added the library manually into the global template (default.hbs). Thus, it's served from my server. As for the styling, the default theme is a light theme which didn't match with my blog at all. Thus, I switched to a theme called "An old hope", with nice and contrasted Star Wars colours, as you can see above.

I had to make some little changes to the CSS directives to make it fit perfectly with my design. I am now very satisfied with the result.

I noticed that highlight.js is very good at colouring code blocks even when no language is specified (what I talked about at the beginning of the post).

That's great because I didn't specify anything for most of my posts, because there wasn't any point in doing so. Some blocks are coloured even though they should be just simple plain text. For those, I just have to specify the language as plaintext. Easy!