How To Make A Next JS Blog With Markdown And TypeScript

Create a server side rendered blog with next js, markdown, and typescript

Cleggacus
Geek Culture

--

Next js blog with markdown and typescript
Next js blog with markdown and typescript

Setup

This medium tutorial will show you how to make a Next js blog with markdown and typescript. Next js is a React framework that will allow you to SSR (server side render), boosting its SEO performance. SEO optimization will allow you to increase your social presence on Google search. Whether you’re a student, a freelancer, or working as a web 2.0 developer, this is an essential skill to have when becoming a professional web developer.

The easiest way to start the project is with the create next app typescript boilerplate.

# with yarn
yarn create next-app blog --typescript
# with npm
npx create-next-app blog --ts

After this, you will need to install all the relevant dependencies.

gray-matter is used to read the metadata such as the thumbnail, description, and title. react-markdown is used to render out the markdown into HTML. react-syntax-highlighter is used to add syntax highlighting to the code blocks within the rendered markdown.

# with yarn
yarn add gray-matter react-markdown react-syntax-highlighter
yarn add @types/react-syntax-highlighter --dev
# with npm
npm install gray-matter react-markdown react-syntax-highlighter
npm install @types/react-syntax-highlighter --save-dev

remove pages/api directory since it is not needed

Create Articles

Create a directory named uploads with some template markdown files. Metadata is surrounded by 3 dashes and has a title, description, and thumbnail. An example of an article is below. The name of the file will be the URL slug.

---
title: Eget Duis Sem Tincidunt Ac Ullamcorper Et Turpis Magna Viverra
description: risus eu lectus a consectetur aliquam nullam enim tellus urna nunc sagittis aenean aliquam ullamcorper consectetur dictumst sit, placerat eget lobortis eget elit nibh blandit scelerisque consectetur condimentum diam tempor. nisl erat semper gravida tempor aliquam suscipit a viverra molestie sit porta cras ultricies, fermentum habitasse sit semper cum eu eget lacus purus viverra cursus porttitor nisi nisl.thumbnail: https://blogthing-strapi.cleggacus.com/uploads/0_d65573c0b9.jpg
---
# In Eu Sapien Tellus Id
## Ullamcorper Elit Semper Ultricies Morbi
sit at blandit cras id eu congue et platea massa lectus netus vulputate suspendisse sed, risus habitasse at purus nibh viverra elementum viverra arcu id vulputate vel. ipsum tincidunt lorem habitant dis nulla consectetur tincidunt iaculis adipiscing erat enim, ultrices etiam mollis volutpat est vestibulum aliquam lorem elit natoque metus dui est elit. mollis sit tincidunt mauris porttitor pellentesque at nisl pulvinar tortor egestas habitant hac, metus blandit scelerisque in aliquet tellus enim viverra sed eu neque placerat lobortis a. laoreet tempus posuere magna amet nec eget vitae pretium enim magnis, cras sem eget amet id risus pellentesque auctor quis nunc tincidunt tortor massa nisl velit tortor. a volutpat malesuada nisi habitasse id volutpat nibh volutpat suspendisse nunc justo elementum ac nec, elementum pulvinar enim sociis nunc eleifend malesuada platea nunc posuere aliquet ipsum.```ts
function someFunc(thing: string){
const thing2 = thing[0];
return thing2;
}
```

Interfaces

Before adding code it is best to create an interfaces directory and add some interfaces so we know the structure of the data that is fetched. These interfaces will make use that the metadata and info of an article post follow a set structure.

Components

We can now create a components directory that will store all components used in the project. This will include a card component and a markdown component which will hold our code for rendering our markdown with syntax highlighting.

Card Component

The card component will take in the property article which will be of type ArticleMeta. This is declared in the interface IProps.

components/card.tsx

The card is styled so that it can be in a grid made with CSS flex.

styles/card.module.css

Markdown Component

The markdown component will take the prop content. Content is a string that holds the markdown code to be rendered.

To style the markdown it is surrounded by a div tag with the class name markdown-body. Copy the CSS file from https://github.com/cleggacus/next-blog-medium-tutorial/blob/master/styles/markdown.css and save it as styles/markdown.css

Add the line below to your _app.tsx file to import the CSS file.

import '../styles/markdown.css'

Pages

There are 2 pages that are needed: an index page and an article page. The index page will show all the articles in a grid and the article page will show all the contents of the article.

Index Page

Start by removing all the contents from pages/index.tsx.

The articles are passed to the home component and mapped to card components.

Then we can fetch the articles with getStaticProps. Get static props is an async function that will statically generate the page with the fetched data returned from the function.

fs.readdirSync(“uploads”) is used to get an array of all the files in the uploads directory.

const files = fs.readdirSync("uploads");

The files are then read and mapped to an array of ArticleMeta. The files are read using readFileSync and casting it to a string.

const data = fs.readFileSync(`uploads/${file}`).toString();

matter(string).data will return the metadata of the markdown. The slug is then generated by splitting at the ‘.’ char and getting the string at index 0. This will remove the ‘.md’ extension of the filename.

return {
...matter(data).data,
slug: file.split('.')[0]
}

The full code of getStaticProps is below.

The final index.tsx file is shown in the code below

styles/Home.module.scss

Cards on index home page

Article Page

The article file is at the location ‘pages/article/[slug].tsx’

The article component takes an article prop of type ArticleInfo to create the article page.

The square brackets in the file name are used for a dynamic route. To statically generate the article pages the getStaticPaths function is used. getStaticProps will return an array of all the routes that have a page.

Each file in the uploads directory is mapped to an array of routes. The routes are the slugs of the articles. The slug is generated the same way it was on the home page.

After the paths are generated each page is rendered. The slug is taken in through the ctx parameter.

const {slug} = ctx.params;

The filename is found with the slug by adding the ‘.md’ extension back on the end of the slug. The info in the file is then parsed by using gray matter.

matter(string).data will return the metadata of the Markdown.

matter(string).content will return the body of the Markdown.

The data and content are added to an object called article which is of type ArticleInfo.

The complete code for pages/article/[slug].tsx is below.

The CSS for the article page is at styles/aricle.css

In conclusion, next js can easily be used as a way to server-side render react code. We have used both getStaticProps and getStaticPaths to general static pages with the static and dynamic routes.

Get the full source code for this project at https://github.com/cleggacus/next-blog-medium-tutorial

--

--

Cleggacus
Geek Culture

I am a fullstack web developer from the UK who writes tutorials on how to use modern web technologies through real projects.