Rendering markdown in Vue 3
Published on August 7, 22'
vue3
vue
markdown

Table of contents

Introduction

Markdown can be incredibly useful for displaying and storing formatted text. For instance the famous readme.md files that can come with a repository.

The syntax is simple - yet effective. A rudimentary example for instance would be a table:

| Syntax    | Description |
| --------- | ----------- |
| Header    | Title       |
| Paragraph | Text        |

Which results in the following:

Syntax Description
Header Title
Paragraph Text

Or perhaps, a list:

- Bacon
- Ham
- Eggs

Touché:

  • Bacon
  • Ham
  • Eggs

So, how does one turn the unformatted markdown text into something more suited for the viewing eyes?

Thankfully someone had already made a tool for this called markdown-it, otherwise you'd have to make your own parser which would be a pain.

Markdown-it

Markdown-it is a javascript markdown parser, exported as a function which produces pure HTML that someone can use however they like. Also it has a great array of plugins and features, as explained on the GitHub page.

Making a Vue component out of it is incredibly easy, the only requirement being that you install and import the markdown-it function and use the render method after setting a few parameters.

Requirements and plugins

First things first - installing the dependencies.

The most important one being markdown-it itself:

npm i markdown-it

or

yarn add markdown-it

The other, more useful, plugins are recommended as some features are not supported by markdown-it by default:

The IEEE is a professional association for electronic engineering and electrical engineering (and associated disciplines) with its corporate office in New York City and its operations center in Piscataway, New Jersey.

```c

int a[255];

int main() {

⠀⠀int *b = a;

⠀⠀printf("%d", *b);

⠀⠀return 0;

}

```

The code above, when a language is specified, produces the following when in triple backticks:

int a[255];

int main() {
	int *b = a;
	
	printf("%d", *b);
	
	return 0;
}

An example:

  • Do the dishes
  • Cook food
  • Buy the groceries

Writing the component

After importing the markdown-it package and its plugins, one can generate an output using the render method:

import MarkdownIt from "markdown-it";

const markdown = new MarkdownIt();

markdown.render("# Header");

Which should, as a result, produce the following:

<h1>Header</h1>

You can also throw in the plugins we mentioned before:

const markdown = new MarkdownIt()
  .use(MarkdownItAbbr)
  .use(MarkdownItAnchor)
  .use(MarkdownItFootnote)
  .use(MarkdownItHighlightjs)
  .use(MarkdownItSub)
  .use(MarkdownItSup)
  .use(MarkdownItTasklists);

The rest is just defining a string prop the component should use to display the desired text and using the regular Vue syntax:

<template>
  <div v-html="markdown.render(source)" />
</template>

<script setup lang="ts">
import MarkdownIt from "markdown-it";
import MarkdownItAbbr from "markdown-it-abbr";
import MarkdownItAnchor from "markdown-it-anchor";
import MarkdownItFootnote from "markdown-it-footnote";
import MarkdownItHighlightjs from "markdown-it-highlightjs";
import MarkdownItSub from "markdown-it-sub";
import MarkdownItSup from "markdown-it-sup";
import MarkdownItTasklists from "markdown-it-task-lists";
import MarkdownItTOC from "markdown-it-toc-done-right";

const markdown = new MarkdownIt()
  .use(MarkdownItAbbr)
  .use(MarkdownItAnchor)
  .use(MarkdownItFootnote)
  .use(MarkdownItHighlightjs)
  .use(MarkdownItSub)
  .use(MarkdownItSup)
  .use(MarkdownItTasklists)
  .use(MarkdownItTOC);

defineProps({
  source: {
    type: String,
    default: ""
  }
});
</script>

And use as so:

<MarkdownRenderer :source="'# Hi!!'" />
©   Matija Novosel 2024