Jack

2023-06-25

Building a Next.js and PicoCSS Blog: A Beginner's Guide - Part 1

ReactNextJSVercelMarkdown
7 min read

What is this post about?

This is the website for Veyxzer. It is built with React and NextJS, and is hosted on Vercel. We use Markdown to write the content of the website.

During this post, we will go through the steps to create a small website like the current one you are reading.

At the end of this post, you will have a website that looks like this: My MD Blog

Prerequisites

Before you start with this guide, make sure you have Node.js installed on your system. You can verify the installation by running the following command in your terminal:

node -v

If Node.js is installed, it should return the version number.

Step 1: Create a New Next.js Project

npx create-next-app@latest --typescript my-md-blog

You will be asked a few questions about the project. You can answer them as you want, but I recommend to use the following configuration:

create-next-app wizard

This will create a new NextJS project in the my-md-blog folder. We can then go into this folder and start the development server:

cd my-md-blog
npm run dev

Here we have the default NextJS project. If you go to localhost:3000, you will see the default NextJS page. We will empty the files content of layout.tsx, page.tsx and globals.css that are inside the src/app folder.

// src/app/layout.tsx
import "./globals.css"

export const metadata = {
  title: "My MD Blog",
  description: "A blog about stuff"
}

export default function RootLayout({
  children
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
// src/app/page.tsx
export default function Home() {
  return (
    <>
      <h1>My MD Blog</h1>
      <p>A blog about stuff</p>
    </>
  )
}
// src/app/globals.scss
@tailwind base;
@tailwind components;
@tailwind utilities;

Step 2: Install PicoCSS

Next, install sass and PicoCSS using npm.

npm install sass @picocss/pico

Then, import the PicoCSS stylesheet in the src/styles/theme.scss file:

// src/styles/theme.scss

// Set a custom primary color
$primary-hue: 50;

// Import Pico
@import "@picocss/pico/scss/pico";

To use PicoCSS, we need to import the stylesheet in the src/app/layout.tsx file:

// src/app/layout.tsx
import "./globals.css"
import "../style/theme.scss"

...

Now run the development server again:

npm run dev

You should see the default NextJS page with the PicoCSS styles applied.

If you add a <button> element in the src/app/page.tsx file, you will see that the button is styled with PicoCSS.

Step 3: Create a Markdown File

During the following steps, we will create a Markdown file and display it on the website. To do so we need to create the .md file, populate it with a header (to add metadata) and some content, and then parse it to HTML. We will also add syntax highlighting to the code blocks so that its more readable.

Create the Markdown File

Create a new file in the src/app/_posts folder and name it my-md-post.md. This file will contain the content of the blog post.

Note: the _posts has a _ at the beginning of its name. This is because we don't want NextJS to create a page for this folder. NextJS will ignore its content.

We will add some metadata to the Markdown file. This metadata will be used to display the title, description, and date of the blog post. The gray-matter package will be used to parse the metadata.

Understanding gray-matter

Before we jump into parsing our markdown files, let's take a brief moment to understand what gray-matter is and why we need it.

gray-matter is a library that helps us parse front-matter from a string or file. Front-matter allows us to keep metadata attached to an instance of a piece of content, saved at the beginning of the file and it uses YAML or JSON syntax.

In our case, it allows us to keep important information about our blog post (like the title, author, date, and tags) in an easy-to-read and easy-to-access manner. Once we've extracted this information, we can use it to render our blog post with all the details our users want to know.

Add Metadata to the Markdown File

Inside the file src/app/_posts/my-md-post.md, we will add the following metadata at the top:

---
author: Jack
title: My MD Post
date: 2021-06-25
tags: [React, NextJS, PicoCSS, Markdown]
---

Add Content to the Markdown File

We will add some content to the Markdown file. This content will be displayed on the website.

# This blog post is written in Markdown

This content is written in Markdown. It will be parsed to HTML and displayed on the website.

Step 4: Parse the Markdown File & Display it on the Website

We will use the gray-matter package to parse the Markdown file and extract the metadata and content.

npm install gray-matter

We add a new file src/lib/mdHandler.ts that will contain the code to parse the Markdown file.

First, we will create a function that will read the Markdown file and return the metadata and content.

// src/lib/mdHandler.ts

import fs from "fs"

export function readMarkdownFile(filePath: string) {
  const fileContent = fs.readFileSync(filePath, "utf8")

  return parseMarkdownFile(fileContent)
}

Then, we need to code parseMarkdownFile that will parse the Markdown file and return the metadata and content.

// src/lib/mdHandler.ts
...

import matter from "gray-matter"

export function parseMarkdownFile(fileContent: string) {
  const { data, content } = matter(fileContent)

  return {
    data,
    content
  }
}

Finally, we need to add a function that will parse the Markdown content to HTML.

We will use this code in the src/app/page.tsx file to display the content of the Markdown file.

// src/app/page.tsx

import path from "path"

import { readMarkdownFile } from "../lib/mdHandler"

export default function Home() {
  const { data, content } = readMarkdownFile(
    path.join(process.cwd(), "src/app/_posts", "my-md-post.md")
  )

  return (
    <>
      <div className="container">
        <h1>{data.title}</h1>
        <p>{data.description}</p>
        <p>{content}</p>
      </div>
    </>
  )
}

You should now see the content of the Markdown file displayed on the website. The content is not styled yet because we only extract the content of the Markdown file without transforming it to HTML. The title is styled because we use the data.title property of the Markdown metadata.

Note: We are using the container class from PicoCSS to center the content of the page. Note: At this point, the markdown content we're displaying on our page is still in its raw form. In the next post, we'll transform this markdown into HTML, making it more readable and user-friendly.

Further Reading

Excited about what you've learned and eager to know more? Here are some resources you might find useful:

Stay tuned for the next post where we'll add syntax highlighting to our code blocks and improve the website navigation. We will also load the Markdown files dynamically and display them as a list on a dedicated page