Skip to content

Latest commit

 

History

History
96 lines (69 loc) · 4.88 KB

README.md

File metadata and controls

96 lines (69 loc) · 4.88 KB

Blog

My personal blog powered by nextjs + TypeScript with articles stored as *.md files.
This was created mainly for learning purposes and maybe for some thought-sharing process in future as well.

Deployed to GitHub Pages.

Available at: https://kicu.github.io/blog/posts

Tech stack

  • nextjs 9.5
  • React 16
  • remarkjs (with plugins) for parsing md files
  • eslint + prettier custom setup
  • styled with pure vanilla CSS (yes!)

About the project

This is my first (non-trivial) project using nextjs + TypeScript.
Also my first adventure with a JAM-ish architecture (https://jamstack.org)

The basic gist is this:
Leverage nextjs static generation to have a simple blog, where every article would be a single *.md file (with some additional metadata) that gets transformed to html markdown and served by React.

My current intention is to keep this as purely static (SSG). I'm not using any kind of SSR/refreshing capabilities that come from next. The main caveat is that a new build will have to be made manually every time a new post is added. This should be good enough for now.

How it works ⚙️

There are 3 pages

  • / - static empty page (with dynamic redirect to /posts), might be used in future to serve something
  • /posts - list of all posts, no pagination yet
  • /posts/<slug> - a single post page

Posts are kept in /db directory which is gitignored. This is because I don't want to publish all the sources of my posts to version control, as it is not needed for the site to work.
In addition I plan to have some private posts which I would like to not be available on web.
The obvious downside to this setup is that the build can only work on my local machine where there are posts - CI builds would not work.
My mind model is that this /db directory should be treated more like a database and not like other source files.

For /posts page:

  • read the whole "db" directory to get a list of posts
  • parse markdown to extract metadata using YAML Front Matter see below
  • pass to nextjs page component

For /posts/<slug> page:

  • read a single file by the provided slug (filename)
  • parse markdown, extract metadata and transform markdown into html using remark
  • pass the post/metadata to nextjs page
  • this page also requires the list of all posts via getStaticPaths to be able to pre-render every Post page on in build time

Actual post content is injected to frontend via the notorious dangerouslySetInnerHTML React prop. Since posts come from "db" and are transformed on the server side only there should be no XSS surface (I hope).

Posts format 📄

The posts are simple markdown files. 1 post == 1 *.md file.
In future I could consider also supporting mdx format.

Front Matter

I learned about Front Matter from docusaurus.
It's a tiny bit of header containing some data, separated from the rest of the docs by a special delimiter (--- in my case):

---
some: data
foo: bar
---

In this project it is used to keep post metadata like: title, html slug of the post etc.

As an example the "hello-world" post is commited to repository.

Private posts

As mentioned earlier I want to be able to write some posts which will be "private". I don't want them to be accessible on the web by anyone - neither inside version control, nextjs build artifacts and of course on the actual blog.

To achieve this there is a property isPrivate inside post metadata and articles that have this set to true will be filtered out, and next will not be rendering these pages. This is controlled via specific env var which is injected into next/config.

Deployment

Currently deployment is done manually via running build-gh-pages script, commiting build artifacts to a dedicated branch in git and then pushing the commit to remote.

I have setup GitHub Pages to be served from branch static-build from directory /docs.

Things to improve/that I'm not happy with 🔨

  • add some tests
  • refactor file/directory structure of src/posts - not happy with 6-7 flat files laying there; possibly group them somehow by roles (repository/service/md parsing etc)
  • add stylelint
  • improve TS typings (enable strict mode?)
  • automatic deployment

Useful links and sources