Nextjs
Published in

Nextjs

NEXTJS + MARKDOWN + TAG+ CATEGORY + BLOG

Build the static blog with Next.js and Markdown

I Build an entire static blog with markdown categories and tags support in the nextjs app. #Series two

In the previous article, we build a project Setup, Layout, Home and Reading page, and In the article, we make the category or tag page for the nextjs blog.

All the codes are available on GitHub Repo. You can also check the final website demo with vercel.

In the nextjs article, we create the search functionality in a static blog.

Content

  1. Project Setup
  2. Project Structure
  3. Posts And Images Dummy data
  4. Pages
  5. Layout
  6. Home Page
  7. Reading page
  8. Category Page
  9. Tag Page
  10. Search Page
  11. SEO
Following the nextjs and markdown series, Firstly, I recommended watching Traversy media. after following the article for a better understanding

Category Page

category page helps to build all the category pages in build time. We use the nextjs functionality to build the static category page. we use getStaticPaths and getStaticProps.

The path for category looks like pages/category/[slug].js

  1. getStaticPaths: Generate all the pages on build time.
  2. getStaticProps: Get the post data and pass the component.

First, import the npm and node packages on top of the file for the category page.

import fs from 'fs'import path from 'path'import matter from 'gray-matter'

getStaticPaths

Firstly we get all posts from the posts folder using nodejs fs and path module.

const files = fs.readdirSync(path.join('posts'))

fs module provides a lot of inbuilt functions, but we use readdirSync with path functions.

let tempStorage = []// Get slug and frontmatter from postsconst temppaths = files.map((filename) => {// Read forntmatter data
const markdownWithMeta = fs.readFileSync(
path.join('posts', filename),'utf-8')// convert data into JOSN
const { data: frontmatter } = matter(markdownWithMeta)
// get all publish articles and pass slug into paramsif (frontmatter.draft === false) {// Get all categories and convert each category in to slug. after push into tempStorage frontmatter.categories.map( category => { let slug = slugify(category) tempStorage.push({ params: { slug } }); })} else {return null}})

Collect all the posts in tempStorage variable then filter the post path.

const paths = tempStorage.filter((item,index) => {return tempStorage.indexOf(item) === index})

Then return all the paths in getStaticPaths

return {paths,fallback: false,}

Summaries the getStaticPaths code below down.

export async function getStaticPaths() {const files = fs.readdirSync(path.join('posts'))let tempStorage = []// Get slug and frontmatter from postsconst temppaths = files.map((filename) => {const markdownWithMeta = fs.readFileSync(path.join('posts', filename),'utf-8')const { data: frontmatter } = matter(markdownWithMeta)// get publish postif (frontmatter.draft === false) {frontmatter.categories.map(category => {
let slug = slugify(category)tempStorage.push({ params: { slug } });})} else {return null}})

getStaticProps

We fetch all categories and pass them to props based on the category slug. Firstly collect all posts in the posts folder.

// Get files from the posts dirconst files = fs.readdirSync(path.join('posts'))

After checking all post base categories, slug and store into tempStorage . Convert category name into slug use of slugify function.

let tempStorage = []// Get slug and frontmatter from postsconst tempPosts = files.map((filename) => {// Get frontmatterconst markdownWithMeta = fs.readFileSync( path.join('posts', filename), 'utf-8' )const { data: frontmatter } = matter(markdownWithMeta)
// check all publish post
if (frontmatter.draft === false) {frontmatter.categories.map( category => {
// convert into slug
let categroySlug = slugify(category)
if (slug === categroySlug) { tempStorage.push({ post: frontmatter }) }})} else {return null}})

Remove all the null posts into tempStorage variable.

//  remove null in tempPostsconst posts = tempStorage.filter(post => {   return post && post})

In the end return, all posts the based on category.

return {    props: {  posts  },}

Summaries all the getStaticProps code down below.

export async function getStaticProps({ params: { slug } }) {// Get files from the posts dirconst files = fs.readdirSync(path.join('posts'))let tempStorage = []
// Get slug and frontmatter from posts
const tempPosts = files.map((filename) => {
// Get frontmatter
const markdownWithMeta = fs.readFileSync(path.join('posts', filename),'utf-8')const { data: frontmatter } = matter(markdownWithMeta)// get publish postif (frontmatter.draft === false) { frontmatter.categories.map( category => { let categroySlug = slugify(category) if (slug === categroySlug) { tempStorage.push({ post: frontmatter })}})} else {return null}})// remove null in tempPostsconst posts = tempStorage.filter(post => { return post && post })return { props: { posts },}}

Category UI Page

export default function Category({ posts }) {return (<div className="container my-3">    <div className="row">        <div className="col-lg-10 post-date m-1 p-2m-auto">{    posts.map((post, index) => {        return <ItemPost key={index} post={post} />})}</div></div></div>)}

Tag Page

The tag page has similar functionality to the category page. You copy the category page code and change all the category names to tag.

The path for category looks like pages/tag/[slug].js

getStaticPaths

export async function getStaticPaths() {// get all posts form postsconst files = fs.readdirSync(path.join('posts'))let tempStorage = []// get posts slug and meta dataconst temppaths = files.map((filename) => {const markdownWithMeta = fs.readFileSync(path.join('posts', filename),'utf-8')// get frontmatter data form postsconst { data: frontmatter } = matter(markdownWithMeta)// get publish post if (frontmatter.draft === false) {frontmatter.tags.map(tag => {
// convert into slug
let slug = slugify(tag)tempStorage.push({ params: { slug } });})} else {return null}})// filter postsconst paths = tempStorage.filter((item, index) => {return tempStorage.indexOf(item) === index})
return { paths, fallback: false, }
}

getStaticProps

export async function getStaticProps({ params: { slug } }) {// Get files from the posts dirconst files = fs.readdirSync(path.join('posts'))let tempStorage = []// Get slug and frontmatter from postsconst tempPosts = files.map((filename) => {// Get frontmatterconst markdownWithMeta = fs.readFileSync(path.join('posts', filename), 'utf-8' )const { data: frontmatter } = matter(markdownWithMeta)if (frontmatter.draft === false) {frontmatter.tags.map(tag => {       let tagSlug = slugify(tag)      if (slug === tagSlug) {        tempStorage.push({ post: frontmatter })       }})} else {return null}})//  remove null in tempPostsconst posts = tempStorage.filter(post => {  return post && post})return { props: { posts },}}

Tag Page UI

export default function tag({ posts }) {return (<div className="container my-3">     <div className="row">       <div className="col-lg-10 post-date m-1 p-2m-auto">{  posts.map((post, index) => {     return <ItemPost key={index} post={post} />})}</div></div></div></>)}

Conclusion

I know my article is hard to understand, so I recommended the following two setups.

  1. Play with code, and the code is available on GitHub.
  2. IF you are a beginner, watch the Traversy media tutorial on nextjs and markdown. Then follow my series.

You can follow me on Twitter and tweet with me.

https://twitter.com/@Official_R_deep

Suppose you like more articles about Linux, Ubuntu, and Raspberry pi 4. Then you visit my website.

https://officialrajdeepsingh.dev/

Read More content at Nextjs. Sign up for a free newsletter and join the nextjs community on medium.

--

--

--

Nextjs Publication is an unofficial publication of Nextjs. Our goal is to bring beginners and pro developer in one place, and everybody understands the basic concept of next.js.

Recommended from Medium

You Think Flux is Over Because You Don’t Understand It

Pillars of JavaScript: Type Conversion

Integrating Chromecast in React Native Applications!

Creating Firefox browser extensions-23

How to make synchronous API Request In Angular ?

Instantiation Patterns in JavaScript

What is strict mode in JavaScript?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Rajdeep singh

Rajdeep singh

JavaScript || Reactjs || Nextjs || Python || Rust || Biotechnology || Bioinformatic || Front-end Developer || Writer || https://officialrajdeepsingh.dev/

More from Medium

Build the static blog with Next.js and Markdown

Static site generation blog with markdown and nextjs

Building a Video Chat App with Next.js, 100ms, and TailwindCSS

How to build SPA with NextJS

Build Restaurant Website with Next.js and Cosmic