Next.js Markdown blog
— 1 min read
Next.js is a great React framework. It's easy to use and lightweight. I use it on my personal website (toukopeltomaa.com).
In this post I'm going to show how to make a simple blog using Markdown and Next.js.
1. Create folder for all Markdown files
Create a folder named posts root of your project. Create all of your posts as Markdown there
Example Markdown file in posts/example-post.md
1---2title: Example post3date: 13-11-20184writtenBy: Touko Peltomaa5---6## Example post
2. Add Webpack plugin raw-loader to next.config.js
We need raw-loader to load Markdown files
1npm i -D raw-loader
next.config.js file
Create next.config.js to your project's root folder if you haven't already
1module.exports = {2 webpack: (config) => {3 config.module.rules.push({4 test: /\.md$/,5 use: 'raw-loader'6 });78 return config9 }10}
3. Create home page at pages/index.js
Parse posts
We are going to parse posts with gray-matter library
gray-matter library will parse the YAML metadata. We can use the YAML data for SEO, written by and post dates.
1npm i -S gray-matter
Gets posts from posts/* folder
1import React from 'react'2import matter from 'gray-matter';3import Link from 'next/link';45export default class extends React.Component {6 static async getInitialProps() {7 // Get posts from folder8 const posts = (ctx => {9 const keys = ctx.keys();10 const values = keys.map(ctx);1112 const data = keys.map((key, index) => {13 // Create slug from filename14 const slug = key.replace(/^.*[\\\/]/, '').split('.').slice(0, -1).join('.');15 const value = values[index];1617 // Parse document18 const document = matter(value);1920 return {21 document,22 slug23 };24 });2526 return data;27 })(require.context('../posts', true, /\.md$/));2829 return {30 posts31 };32 }3334 render() {35 return (36 <>37 <h1>Posts</h1>38 {this.props.posts.map(({ document: { data }, slug }) => (39 <Link href={{ pathname: '/post', query: { id: slug } }} key={slug}>40 <h2>{data.title}</h2>41 </Link>42 ))}43 </>44 )45 }46}
The getInitialProps
function gets posts from posts folder and returns them in a usable format. We are going to use your filename as our post's slug or id
3. Create post page at pages/post.js
Get document name from querystring, require it and parse it.
Install React Markdown
To render Markdown we are going to use react-markdown
1npm i -S react-markdown
1import React from 'react'2import matter from 'gray-matter';3import ReactMarkdown from 'react-markdown';45export default class extends React.Component {6 static async getInitialProps({ query }) {7 const post = await import(`../posts/${query.id}.md`);8 const document = matter(post.default);910 return {11 ...document12 };13 }1415 render() {16 return (17 <>18 <h1>{this.props.data.title}</h1>19 <i>{`Written by ${this.props.data.writtenBy} | ${this.props.data.date}`}</i>20 <ReactMarkdown source={this.props.content} />21 </>22 )23 }24}