Making a Markdown Editor for Your Vue Blog with Front Matter Support
Tags: webdev, vue, productivity
Published: 2021-01-17 17:10:41

---
title: Making a Markdown Editor for Your Vue Blog with Front Matter Support
published: true
description: A tutorial on how to make a markdown editor component in Vue Js that has build-in front-matter support.
tags: webdev, vue, productivity
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/sfi16opa0yrmoh1wzzbz.jpg
canonical_url: https://jamesinkala.com/blog/making-a-markdown-editor-for-your-vue-blog-with-front-matter-support/
---

Markdown is a plain text format for writing structured documents, based on formatting conventions from email and usenet. On the other hand, front matter in the article's context is simply [YAML's front matter block](https://jekyllrb.com/docs/front-matter) which I can assume, was inspired by the same word as used in book design.
Example from the following block,
```yaml
---
title: Outline title
description: The shortest description ever written.
---
```
we can obtain the following object:
```js
{
  title: 'Outline title',
  description: 'The shortest description ever written'
}
```
We'll be using the [front-matter](https://github.com/jxson/front-matter) npm module to achieve this.

The inspiration for this tutorial is DEV.to's basic markdown editor that pushed me to create one for my own website.
Using front matter in the editor is a sound concept since it is better to have all article meta-data such as title, tags, description etc within the article content area than having a form with several input fields.

## Creating The Editor ##
What we want is for our editor to take the combination of front-matter data and markup, then be able to extract the two before storing that data separately somewhere. We'll be using the [front-matter](https://github.com/jxson/front-matter) module to extract the data we need from the text editor content.

Here is the editor in action.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zrqpggjslw6iex4jmvt0.gif)

Since we'll be working with markdown and front-matter in our editor, we'll add the two npm modules first.
```sh
$ npm i front-matter marked
```
**Note**: [marked](https://github.com/markedjs/marked) provides the following warning "Marked does not sanitize the output HTML. Please use a sanitize library, like DOMPurify (recommended), sanitize-html or insane on the output HTML!"


[UIKit](https://github.com/uikit/uikit)'s css framework has been used to create the template for the editor as you'll notice from the CSS classes but feel free to style the editor to your liking.


__The Template__
```html
<div id="editor-form-container" class="uk-margin">
  <div id="button-container">
    <button @click.prevent="previewMarkdown = !previewMarkdown" class="uk-button uk-button-primary uk-float-left">{{previewMarkdown ? "Edit Article" : "Preview Article"}}</button>
  </div>
  <div id="editor-container">
    <textarea v-if="!previewMarkdown" id="d1" v-model="allContent" class="uk-textarea editor"></textarea>
    <div v-else class="preview" v-html="compiledMarkdown"></div>
  </div>
</div>
```


__The Javascript__
```js
import Marked from 'marked'
import FrontMatter from 'front-matter'
export default {
  name: "MarkdownEditor", 
 ...
```


__Our Variables__
```js
  ...
  data(){
    return {
      previewMarkdown: false,
      startContent: `---
title: 
short_description: 
tags: 
post_image: 
publish: false
---
Write content here
`,
      allContent:"",
      articleData: "",
    },
  },
  ...
```
__previewMarkdown__: A _bool_ value that toggles the text of our button showing when we are editing or previewing the article.
__startContent__: What the text editor contains when the text editor is mounted.
__allContent__: All of the contents of the text editor at a given time.

```js
  ...
  computed:{
    compiledMarkdown(){
      let data = FrontMatter(this.allContent)
      return Marked(data.body)
    },
  },
  ...
```
The __compiledMarkdown__ computed value returns the processed html from the markdown within __allContent__ which we preview within the block with v-html on the template above.

When the component has been mounted we assign the __startContent__ to the __allContent__ variable.
```js
  ...
  mounted(){
    this.allContent = this.startContent
  },
  ...
```

With the above code we can edit and preview our article. To get the variables passed in the front-matter block we'll add a ___getVariables()___ function and call it when needed.
```js
  ...
  methods: {
    getVariables(){
      const {body, attributes} = FrontMatter(this.allContent)
      $nextTick(()=>{
        articleData = {
          content: body,
          title: attributes.title,
          description: attributes.short_description,
          tags: attributes.tags,
          image: attributes.post_image,
          publish: attributes.publish,
        }
      })
      // Then proceed to using articleData object as needed
    }
  },
  ...
```

This is just a starting point to this markdown editor. More features can be added to it such as text persistence with the help of vuex and the vuex-persistedstate plugin and more.