Rem Kim

Rem Kim - 2020-05-10

Saving blogs as JSON files. Next.js blog Part 2

Saving blogs as JSON files. Next.js blog Part 2

In previous blog I showed how to setup basic Next.js project. Here I will explain how to setup your own CMS and save blogs locally using Lambda functions.

Welcome to part 2 of Setting up Next.js blog!

It is obvious that you need some sort of storage to save your blogs. It could be good old MySQL or Postgres. It could be document storage like MongoDB, or something new and fancy like FaunaDB. In my case I didn't want to use any third party hosting/provider services to store my data and I also wanted to own data. So, I decided to save files locally and use Github as a data storage.


There are few things we will cover while building CMS.

  • Writing markdown and rendering markdown blog content
  • Saving/updating files locally using Lambda functions
  • Listing all blogs from files
  • Making sure you can only save/update/delete in development mode locally

Writing markdown

I didn't want to write HTML for each blog to style it. So the easiest and right way to do it is to use markdown.

I used package react-markdown that allows you to render markdown input as HTML. Now since in my blog I use Chakra UI I had to pass renderer function in order for react-markdown package to know how to render each of markdown elements.

markdown-preview Full blog form code here

This form allows us to write our blog in textarea as a markdown and then preview it using React Markdown package. We will use the same package to render it in blog page.

Saving blog file

We will be using Lambda functions which is Next.js API routes to save blog.

Sending POST request to /api/cms/blogs will save file.

Saving/Listing blog files Click here for code

First of all we need to make sure that incoming request is POST, then we check if we are in development environment, by running devonlyMiddleware which I will describe later. After that we can proceed with saving file.

Here is example structure of the blog file

{ "title": "Newer draft", "tldr": "Some tldr", "tags": [], "content": "", "thumbnail": null, "status": "draft", "author": "Rem Kim", "createdAt": "2020-04-15T02:32:45.034Z", "updatedAt": "2020-04-22T21:19:19.791Z", "slug": "newer-draft", "id": 1586917965034 }

Those are the fields I find useful and need to be saved. For an ID i used current timestamp.

generateFilename generateFilename

getSlug getSlug

and finally saveBlogFile saveBlogFile

I used fileSystem.promises in order to be able to use async/await syntax.

Update/Find blog

Now, in order to find or update blog by its ID, i've added another api route api/cms/blogs/[id] save-find Click to see code

allFiles - This function will scan directory with blog files, reach each one and parse its content to JSON, then output array of blog objects. allFiles

writeJSONToFile and makeFilename write-and-make-filename


I promised we will comeback to this one. Like I said before I want to be able to use all that functionality locally when spinning up local development server. However on production those api functions should error out.

In order to do it I've added devonlyMiddleware devonlyMIddleware


Now with those API routes, I can read/save/update blogs and github becomes my data storage.


© Rem Kim - Powered by Next.js