Loading...

How to Use Vue Components in Markdown Content With Nuxt MDC

Last update: 9/3/2024
Title image for the blog post on how to use Vue components with Nuxt MDC

Intro

The Nuxt MDC module not only allows you to parse and render Markdown but also extends Markdown syntax, enabling the use of Vue components within your Markdown content. This enhances the flexibility of working with Markdown in a Vue/Nuxt context with minimal effort.

In This Guide

We will initiate a new Nuxt 3 project with Nuxt MDC and demonstrate how to integrate custom Vue components into your Markdown content. The Composition API and the <script setup> syntax are used throughout this guide.

Setup

  • Nuxt 3.12.1
  • Vue 3.4.27
  • Nuxt MDC 0.8.2
  • node 18.12.1
  • npm 9.8.1

Prerequisites

  • Basic understanding of Nuxt 3
  • Basic understanding of the Markdown syntax
  • node.js and npm are installed on your machine

Creating a New Nuxt 3 Project

Start by initiating a new Nuxt 3 project and installing Nuxt MDC as follows:

npx nuxi@latest init nuxt3_mdc_code
cd nuxt3_mdc_code
npm install @nuxtjs/mdc

Note the versions stated above!

Enable the Nuxt MDC module in nuxt.config.ts in order to make use of it:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/mdc‘],
})

Using a Vue Component in Markdown Content

Suppose you have a blog with various posts written in Markdown and you want to insert ads within your content. With Nuxt MDC, you can create a separate Vue component, Ad.vue, for the ad and embed it in your Markdown content using the extended syntax provided by Nuxt MDC.

Creating an Ad Component

In order to use the <Ad> component in your Markdown, it must be registered globally by either placing the component under components/global/ or by adding the .global suffix (Ads.global.vue) to the filename when placed in the standard componts/ directory. Refer to the Nuxt documentation on dynamic components for more information.

For demonstration purposes, add the following code to the Ad.vue component und `components/global/:

Ad.vue
<script setup>
const props = defineProps({cssClass: String});
</script>

<template>
  <div class="ad" :class="props.cssClass">
    <div class="ad-header">Ad: <MDCSlot unwrap="p,div" /></div>
    <div class="ad-banner">Place you ad here.</div>
  </div>
</template>

<style scoped>
.ad {
  border: 1px solid #eeeeee;
  border-radius: 5px;
  padding: 10px;
}

.ad-header {
  font-size: 10px;
}

.ad-banner {
  background-color: #eeeeee;
  border: 1px solid #eeeeee;
  border-radius: 5px;
  padding: 10px;
}

.info {
  border-color: orange !important;
}
</style>

Nuxt MDC allows to pass props, from Markdown to the Vue component. The props definition in the Vue component’s <script> section (line 2) must match the props passed from Markdown.

The template contains a wrapper <div class=“ad“ :class="props.cssClass"> with a header and a banner (line 7 and 8). The wrapper element takes a dynamic string value for the class attribute, which can be passed as prop to the <Ad> component. The header contains a <MDCSlot> component to render additional content provided by the Markdown. The <MDCSlot> component comes with Nuxt MDC module and allows to unwraps content from HTML tags - in this case <p> and <div> (Remember that text from Markdown strings are wrapped with a paragraph tag by default). The <div class="ad-banner"> could be replaced with a banner image in a real-world project, but for this demonstration, simple text and CSS are used.

Using the Ad Component in Markdown Content

To use the <Ad> component in your Markdown content, reference the component with the :: identifier, followed by the component`s name:

::ad{cssClass="info"}
<div>Some extra text from the Markdown content.</div>
::

You can pass additional props and HTML to the component from within your Markdown. To pass props to the <Ad> component, add curly braces {} after the component name containing the props you want to pass, like cssClass="info“. You can pass multiple props separated by spaces: ::ad{cssClass="info" anotherProp="someValue“}. Additionally, you can pass HTML to the component, which is then rendered at the position of the <MDCSlot> component. Close the component call with an ending ::.

To render the component in your Nuxt application, adjust the app.vue file as following:

app.vue
<script setup>
const md = `
# Welcome to docs4.dev

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum eum exercitationem harum in iste magni perferendis quo ratione voluptatem voluptatum!

::ad{cssClass="info"}
<div>Some extra text from the Markdown content.</div>
::

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam at blanditiis commodi doloribus facere necessitatibus nemo quo quos totam vero?
`
</script>

<template>
  <div>
    <MDC :value="md" />
  </div>
</template>

The md variable contains the raw Markdown string with dummy text and the <Ad> component, identified by ::ad, as explained above. The <MDC> component from Nuxt MDC parses and renders the Markdown string.

The result looks as follows: Result of Vue components used in Markdown content.

Nuxt MDC also allows you to nest Vue components in your Markdown content or work with named slots. For more information, please refer to the Nuxt Content module documentation.

Summary

The Nuxt MDC module enables the seamless integration of Vue components within your Markdown content. This guide demonstrates how to reference Vue components in Markdown, including passing props, and HTML templates.

Report a problem (E-Mail)