DEV Community

Cover image for Nuxt Content custom markdown block
Kyle Welsby
Kyle Welsby

Posted on

Nuxt Content custom markdown block

During a live-stream on 25th November 2020 I was tackling a feature on my project where I have Markdown within front-matter data I would like to render to the page correctly.

Here I'm quickly sharing some findings after sleeping on the problem and finding an elegant solution to the problem.

tl;dr

Utilise the content:file:beforeInsert hook in nuxt.config.js.

Setup

Assuming you've got a nuxt.js project with @nuxt/content module installed

It is expected you'll have a content file like the following, containing Markdown within a property.

# content/home.md
--------
title: Hello World
specialNotice: |
  This is **Special Notice** to 
  everyone using 
  [Markdown](https://en.wikipedia.org/wiki/Markdown).
--------
Enter fullscreen mode Exit fullscreen mode

Configuration

With the above content, we can see the specialNotice which is formatted using Markdown. So we're going to pre-parse this field and make it accessible for the <nuxt-content /> helper to render the HTML output.

Within nuxt.config.js we're going to add into the hook section a content:file:beforeInsert to convert the Markdown content to JSON ATS which is like a node tree that can be rendered to the page.

// nuxt.config.js
export default {
  // ...
  hooks: {
    // Doc: https://content.nuxtjs.org/advanced#contentfilebeforeinsert
    'content:file:beforeInsert': async (document, database) => {
      // search for markdown containing 
      // only `specialNotice` property.
      if (document.extension === '.md' && 
          document.specialNotice) { 
        // Replace Markdown string in database 
        // with the JSON ATS version
        document.specialNotice = await database 
          .markdown
          .toJSON(document.specialNotice) 
      }
    }
  },
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Displaying

<!-- pages/index.vue -->
<template>
  <div>
    <h1>{{ document.title }}</h1>
    <nuxt-content :document="document.specialNotice" />
  </div>
</template>
<script>
export default {
  async asyncData ({ $content }) {
    const document = await $content('home').fetch()
    return {
      document
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

There we have it; Your page should contain the special notice rendered in HTML.

Follow me on Twitch, YouTube and Twitter for regular live-streams and chat.

Discussion (0)