§ A proof of concept

This is a quick post to show the different ways we can use to make Vue.js components available inside Markdown content.

And at the same time, see how we can import .md files inside Vue.js components.

This is possible thanks to the hard work being done on frontmatter-markdown-loader.

As a starting point, we’ll use the code from the Nuxt.js app we get from following the Quickstart guide for a new Nuxt.js project.

With the app ready, get into its directory and install the frontmatter-markdown-loader:

yarn add --dev frontmatter-markdown-loader

Then add a new webpack rule to nuxt.config.js , this will allow us to import Markdown files:

import Mode from 'frontmatter-markdown-loader/mode' export default { build : { extend (config, ctx) { config.module.rules.push({ test : /\.md$/ , loader : 'frontmatter-markdown-loader' , options : { mode : [Mode.VUE_COMPONENT] } }) } } }

§ Demo content

Now let’s create a new content/blog directory:

mkdir -p content/blog

Create a frontmattered Markdown file at content/blog/my-post.md with this content:

--- title: "Vue.js components inside Markdown" date: 2019-09-01T12:00:00-05:00 categories: ["frontend", "webdev"] tags: ["vue.js", "markdown"] --- # Markdown in my Vue.js in my Markdown in my... Ever wanted to embed some Vue.js components into your Markdown driven blog? Have a look at this: Globally available component: < global-component /> Locally available component: < local-component color = "purple" /> Async loaded component: < async-component color = "error" /> --- **Superb!**

Get used to closing tags when using HTML inside Markdown.

§ Globally available component

Create a components/GlobalComponent.vue file:

< template lang = "pug" > v-btn(:color="color") Global button </ template > < script > export default { props : { color : { default : 'primary' , type : String } } } </ script >

To make it globally available, we need to register it in that way.

Create a new plugin for registering global components at plugins/global-components.js :

import Vue from 'vue' import GlobalComponent from '~/components/GlobalComponent.vue' Vue.component( 'GlobalComponent' , GlobalComponent)

Then in nuxt.config.js :

export default { plugins : [ '~/plugins/global-components.js' ], }

§ Locally available component

Create a components/LocalComponent.vue file:

< template lang = "pug" > v-btn(:color="color") Local button </ template > < script > export default { props : { color : { default : 'primary' , type : String } } } </ script >

§ Async component

Create a components/AsyncComponent.vue file:

< template lang = "pug" > v-btn(:color="color") Async button </ template > < script > export default { props : { color : { default : 'primary' , type : String } } } </ script >

§ Render it all

Let’s take this approach for a spin —Shall we?

For the sake of this PoC, change your pages/index.vue file to this:

< template lang = "pug" > v-card v-card-text //- Here we use/render the Markdown component //- just like we would do with any other my-markdown-post </ template > < script > import LocalComponent from '~/components/LocalComponent.vue' import MyMarkdownPost from '~/content/blog/my-post.md' MyMarkdownPost.vue.component.components = { AsyncComponent : () => import ( '~/components/AsyncComponent.vue' ), LocalComponent } export default { components : { MyMarkdownPost : MyMarkdownPost.vue.component } } </ script >

Launch your dev server with:

yarn dev

Navigate to http://localhost:3000 and you should see something like this:

This is just a stepping stone on my way to writing a full blog system that uses mainly Markdown for content, but can include Vue.js components in a painless way.