How to create a Nuxt based blog markdown driven from scratch

20th September, 2019 - 5 min. read - in Tutorials - Go to Index

Hey, before scrolling, I've made a tool to help people building presentations the modern way.
If you don't mind, I'd like to ask some feedback about it. Here the starting point to learn more.
Much appreciated!

This is a little guide to set up a minimal Nuxt.js based blog with markdown capability.

I’ve already explored this topic here and here and this time I want to explore the same concept using markdown files as the content source.

Nuxt.js is a very good piece of software that provides a very nice development experience without sacrificing top-notch outcomes in terms of performance and reliability as well.

For instance, Nuxt.js allows creating universal Vue based websites, meaning you can build a fully static, SEO-ready, websites using all the features of Vue.js in terms of modern user experience.

I’ve tested it recently with the marketing website of PRESENTA and I was impressed by the speed and the comfort during the development as well as the outcome that is super optimized (PageSpeed gave me 92/99 score for mobile/desktop out of 100) and future-proof (the whole website is fully navigable even with javascript turned off!

I’ve conducted also some stress tests in order to learn whether Nuxt.js can be used to build bigger websites such as products catalogs or news portals. I was able to build a website with more than 1000 markdown files without issues and with a reasonable built time.

This makes Nuxt.js a very good option against another very good static builder that I like a lot, 11ty.

Let’s get started from scratch

Here the step by step assuming you’ve already Node.js+NPM installed, an empty folder on your system and the shell pointing that path.

module.exports = {
  build: {
    extend (config) {
      config.module.rules.push({
        test: /\.md$/,
        loader: 'frontmatter-markdown-loader'
      })
    }
  }
}
<template>
    <div v-html="html"></div>
</template>

<script>
export default {
    async asyncData({params}) {
        return await import(`content/${params.id}.md`)
    }
}
</script>
# Title

### sub title

Some text

> A quote

You should see the rendered page in beautiful basic HTML.

Now you can create as many markdown files as you want in the content root and they will be rendered and properly served according to the browser request.

It’s possible also create different templates for different types of content using subfolders as a way to categorize your content.

What about static pages

So far, the above example is a regular SPA (Single Page Application), not very SEO friendly.

If you want to transform all those markdown files in static HTML files, this way your blog will be SEO ready and backward compatible, here the additional steps to make that happen:

import glob from 'glob'

let files = glob.sync('**/*.md', { cwd: 'content' })
files = files.map(d => d.substr(0, d.lastIndexOf('.')))

module.exports = {
    generate: {
        routes: files
    },
    build: {
      extend (config) {
        config.module.rules.push({
          test: /\.md$/,
          loader: 'frontmatter-markdown-loader'
        })
      }
    }
  }

You should get in dist folder all the website pages generated ready to be served.

What about the sitemap?

If you want to give to your blog some chances to get crawled by the search engines, you need to create also a sitemap of all your pages. Here the futher steps:

import glob from 'glob'

let files = glob.sync('**/*.md', { cwd: 'content' })
files = files.map(d => d.substr(0, d.lastIndexOf('.')))

module.exports = {
    modules: [
        '@nuxtjs/sitemap'
    ],
    sitemap: {
        hostname: 'https://www.example.com'
    },
    generate: {
        routes: files
    },
    build: {
      extend (config) {
        config.module.rules.push({
          test: /\.md$/,
          loader: 'frontmatter-markdown-loader'
        })
      }
    }
  }

Hope this sheds some light on this wonderful library. You can download all the source files from here.

Next post will teach you how to list posts and allows navigation between similar posts.


Spotted a typo or (likely) a grammar error? Send a pull request.