Everyone loves a good syntax highlighting. This post explains how to use highlight.js for syntax highlighting in a Vue.js application. The method shown here allows syntax highlighting both on original creation of an element as well as on updates to the source-code, using a simple v-highlightjs directive such as this:

< pre v-highlightjs >< code class = "javascript" ></ code ></ pre >

You can see a live example here: jsfiddle.net/metachris/1vz9oobc.

To achieve this, we just need to install the highlight.js dependency and create a custom highlightjs directive. Let’s dive straight in!

Note: The code from this post is now also published as npm package vue-highlightjs, which you can easily use in your project.

Install the highlight.js dependency

The first step is to install highlight.js as a dependency with the npm node package manager:

$ npm install --save highlight.js

Include the highlight.js CSS file in your HTML

To reference the highlight.js CSS style sheet from the HTML, just include a <link rel="stylesheet" tag which points to either a downloaded highlight.css file or to their CDN URL:

<!-- Downloaded and saved in /static/css/highlight.css --> < link rel = "stylesheet" href = "/static/css/highlight.css" > <!-- Or if you want to use the stylesheet from the CDN --> < link rel = "stylesheet" href = "//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/styles/default.min.css" >

highlight.js comes with a number of different styles, which are defined by using a specific stylesheet for each style (we are using the default style here). For other available styles look into the highlight.js styles directory (and don’t forget to add “.min” before “.css”).

A custom Vue.js directive: v-highlightjs

To use highlight.js from within Vue.js components, we are going to create a custom Vue.js directive called highlightjs . You can declare this directive directly in your main.js file:

import Vue from 'vue' import hljs from 'highlight.js' ... Vue.directive( 'highlightjs' , { deep: true , bind: function (el, binding) { // on first bind, highlight all targets let targets = el.querySelectorAll( 'code' ) targets.forEach((target) => { // if a value is directly assigned to the directive, use this // instead of the element content. if (binding.value) { target.textContent = binding.value } hljs.highlightBlock(target) }) }, componentUpdated: function (el, binding) { // after an update, re-fill the content and then highlight let targets = el.querySelectorAll( 'code' ) targets.forEach((target) => { if (binding.value) { target.textContent = binding.value hljs.highlightBlock(target) } }) } })

(You can also use the npm package vue-highlightjs instead of declaring the directive manually.)

Using v-highlightjs

To highlight code (for example JavaScript) which is either hardcoded in a template or stored in a variable (or getter) called sourcecode , we can use the v-highlightjs directive like this:

< pre v-highlightjs >< code class = "javascript" >{{ sourcecode }}</ code ></ pre >

highlight.js replaces the content of the <code> block. If using the directive as shown above, updating the source-code after the initial highlighting does not work anymore. To be able to update the code and highlight it again after an update, pass the variable directly into the v-highlightjs directive like this:

< pre v-highlightjs = "sourcecode" >< code class = "javascript" ></ code ></ pre >

Live Example

References

You can reach out to me via @metachris. Please let me know if you have any feedback or suggestions!