Building a static blog site with Markdown and Next.js

In recent times we have seen the emergence of new technologies and the evolution of development tools and services on such a scale that we, as developers, could only dream ten years ago.

We can now build very rich content web sites using high-quality open source libraries in JavaScript and UI libraries that look gorgeous out of the box. Making the job for web developers easier and enabling us to deliver top quality products in less time and focus on functionality, content, and reducing time to production, among others.

With all the development tools and services that allow us to build a complete website without the need to have a server, we began to wonder that, in some cases, it’s enough to have static content deployed in the cloud ( CDN instances) and updated by continuous deployments ( CD).

On the other hand, static sites generators and SSR [¹] frameworks solve one of the problems that SPA suffered since it’s birth. It’s difficult to get Search Engine Optimization or previews of a specific sub-page when sharing on social media, using Single Page Apps, something that can be easily done with Prerendering and/or Server Side [²].

Besides, SSR and static pages are seldom faster that SPA, due to the reduced markdown rendered from the server in comparison to the JS bundle size of and consecutive calls to the APIs needed from the bootstrap to the complete render on a Single Page Application.

Building a static blog site

Today we’re going to build a static blog site using Markdown, and a wonderful SSR React framework called Next.js

For this project, we’ll be using the following packages:

  • React Declarative JS library for UI.
  • Next.js Isomorphic React on the server and the browser
  • Material-UI Gorgeous UI design out the box
  • MDX “JSX in Markdown for ambitious projects.”
  • clsx “A tiny utility for constructing string conditionally"

The source code repository of this project is available here.

Getting started

Let’s begin by creating a new directory for our project, initializing a file and then installing React and Next.js packages,

Next JS has its built-in router system ready to use out the box; we need to create a directory,

And we’ll be adding new pages as React jsx components as we progress building the blog app.

We’re also adding some scripts to ,

To start in development mode, build the static content, and start as in production, respectively.

React components with Material-UI

Continuing with the component library picked option ( Material-UI), first install the library installing,

Now we need to make some modifications that apply to all the served pages in our site. As Material UI and other react libraries rely on its styling engine inside JavaScript (CSS-in-JS for Material-UI), then there is no need for the built-in feature that comes by the default in Next.js. To modify this, we override the configuration by adding a page at,

As you might notice, we’re also adding a to get our custom theme for Material-UI. So the next step is to create a new folder to add new common components as we make progress and also a new file,

With these changes in place, we are ready to start building the layout and new components with Material Design 👌.

Web site layout

The layout for our blog site includes a navbar with the mail link to home (title) and an about link, a section title for Feature Blog posts and a two-column grid displaying cards with the title, date of publication and a summary of the content for each post,

The first component we need to define is that will also be our landing page at , where is the domain for production or simply if we are in development. Then define the index page as follows,

Here we’re making use of other components inside directory such as for the top navigation panel, or for the bottom panel. These components are relatively small and straightforward; you can take a look at these components at my Github repo. But I'd like to elaborate more on the third component and the imported array , as they are the core elements of the micro-blog engine.

Let’s take a look at first,

This is a component that expects a prop that contains a title, publish date, path, or href and summary, as we can see in the layout picture.

Setup Markdown configuration in Next.js

So we need somehow to provide these properties from the blog posts we write in Markdown -inside the pages directory- to the component to display a preview on the land page. How can we do that?. Well, the answer is that our site is static, so we just read them from the file system!.

But before that, we need to install and configure the package we’ll be using to work with Markdown: MDX, which fortunately comes ready to work with Next.js.

We add next and a plugin for next.js,

Then create file and include these contents,

This tells next to import files with extension automatically and process them as they were JSX files, we'll see that our post are actually the both, a JSX React component and a Markdown file at the same time.

Now let’s define the JavaScript utility to load the posts in markdown. Let’s create a folder and inside the file ,

This function looks inside the folder for any file with extension and inside each file, it expects an object called , where the properties of the post (title, path, summary, and publish date) resides, which is what the function exports in the end.

Then let’s look how a blog post show looks like,

That is the first part of a post at (note that I added a sub dir inside pages, to keep the posts apart from the other pages). It starts by importing a React component , which is the frame for the contents of the blog, we'll see it in just a minute. Then we have the meta-object with the meta-data of the blog post, a default export of this JSX file (a react component) and then, finally, the post content! and that's it, how it's we write a post in our blog, simple and neath. 🙂

Dealing with static resources

Going back to our preview of the posts on the index page, we should be able now to import the meta-data and display it in the cards. However, we still need an extra step, as we work with static data, the import should happen at compile-time, and a regular won't work because when it's executed in the browser, it will try to bring data up that is in the server. What is the solution to this challenge? we pre-evaluate the contents given by in the server, before they're served to the client. For this, we'll use a couple of plugins available in babel: and ,

Add a file and the contents,

And we add a file at and this is where the magic happens,

The last line pre-evaluates the contents retrieved by , so we are really exporting the array of meta-objects, instead of the function to fetch them.

Displaying a blog post as a stand-alone page

Finally, we’ll see how a blog post is going to look

We have the navigation and footer panels on the index page. Also, a link “Back to blog” on the upper left, to return to the landing page, a couple of links in the lower section of the post, to go to previous and/or next blog, for what we need to use again here.

…And this is it!. You can now start your awesome blog posts. 🙌🏼

If you wish to go live, there is an excellent hosting option at zeit.com, where you can very quickly deploy your project with direct CD integration with GitHub, and you don’t even need a credit card to start.

Thank you for reading my blog!. Please keep up with the latest updates on my channels. Cheers!.

[¹], [²]: Client-side vs Server-side vs Pre-rendering for Web Apps.

ITNEXT

ITNEXT is a platform for IT developers & software engineers to share knowledge, connect, collaborate, learn and experience next-gen technologies.

Eduardo Pineda

Written by

Passionate full-Stack software developer. https://epineda.dev

ITNEXT

ITNEXT is a platform for IT developers & software engineers to share knowledge, connect, collaborate, learn and experience next-gen technologies.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade