Vue.js in Jekyll

Vue.js is a JavaScript framework that allows you to build reactive, component-based web applications. Jekyll is a rendering engine for blogs, which turns static markdown files into a web blog without the need for databases or complicated web serve setups. It is also the rendering engine I use for this blog, and I am a huge fan of Jekyll.

In this blog post, I’ll briefly explore how to integrate Vue.js components in your Jekyll blog. The marriage of these two frameworks allows you to reuse your blog’s components in some other web app, or vice versa, reuse other components in your blog. So, let’s get our hands dirty.

Requirements

I tried this for Jekyll 4.0.0 with kramdown as markdown renderer, using ruby 2.6.3 and Vue.js 2.x.

Adding Vue to your site

The easiest way to integrate a Vue app to an existing, static HTML site requires only three simple steps: add the Vue library to the site, add a DOM element for the Vue app to live in and finally to define the Vue app. Integration with Jekyll is just a little more complicated than that.

Our first step is to include the Vue library to our site. To do so, we simply have to add a <script> tag to the layout file that we use for our page.

Vue offers two different versions of its library, development and production. The development version is optimized for debugging and understandability, whereas the production version is optimized for speed. Since I don’t want to change the link all the time, I will make the version of the Vue library dependent on the Jekyll environment.

{% if jekyll.environment == "production" %}
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>
{% else %}
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
{% endif %}

Then, we need to define the DOM element where the Vue app can live in. Typically, that is a <div> with an id ‘app’, but it can be any valid DOM element with any valid selector. By default, kramdown filters curly braces, so the DOM element in kramdown needs to be preceded by a raw directive and succeeded by an endraw directive, which stops the kramdown from interpreting the content.

{% raw %}
<div id="app">
{{message}}
</div>
{ % endraw %}

Please note that in the code sample before there is an extra space in between the opening curly brace and the percentage sign which needs to be removed in your Jekyll post. It should look like this {% endraw %}. However, since this is a Jekyll page, I cannot use the directive directly, because it would the previous raw directive.

Finally, we need to define our Vue.js app in our page. We’ll stick to the hello world example. Kramdown supports JavaScript, so adding JavaScript works like in a regular HTML page by simply have to put it between <script> </script> tags.

<script>
const app = new Vue({
  el: '#app',
  data: {
   message: 'Hello Jekyll'
  }
})
</script>

That’s it. Your post should now display “Hello Jekyll”.

Vue.js components in Jekyll

One of the main strength of Vue.js is that it allows creating component-based web apps. Such components can be viewed as building blocks of web apps, which is pretty neat. Adding components to a Jekyll post is pretty straight forward. The only thing you have to be aware of is that curly braces need to be escaped. So if you define your component within a script tag, then you need to add surrounding {% endraw %} directives.

{% raw %}
<script>
Vue.component('hello-component', {
  props:['text'],
  template: '<h3>test {{ text }}</h3>'
})
</script>
{ % endraw %}

The component definition needs to be included before adding the app definition, but after including the Vue.js sources. Alternatively, you can also include your component in a .js file, for example like this:

<script src="{{site.baseurl}}/assets/components/hello-component.js" > </script>

Integrating Vue.js like I described before allows you to quickly add some nice Vue-powered apps to your blog post. This is nice for some small additions to your page, but as soon as your app becomes more complex, single file components may be better suited.

Single file Vue components in Jekyll

Single file components allow you to nicely encapsulate your Vue components in a file. Typically, you need to run a Vue pre-processor to translate such single file components into plain JavaScript, HTML and CSS which can be read by a browser.

Jekyll is also a pre-processor, which takes kramdown- and template files to create some HTML, JavaScript and CSS that browsers can read. Running two pre-processors that are not built for each poses some obvious problems.

There is a simpler, yet hackier way to include the single file components, namely via using the http-vue-loader-library. To do so, all you need to do is include the http-vue-library before instantiating the Vue app and include your componets via the httpVueLoader-method.

<script src="https://unpkg.com/http-vue-loader"></script>

...
// in Vue app declaration
components: {
  'my-component': httpVueLoader('./components/my-component.vue')
}

...