Creating this Blog with Next.js

this blogpost is a work in progress

Introduction

The goal of this blog software is to allow creators to write and share blogposts in a simple way. There is an earlier version made exclusively with React. It uses Googles Firebase for authentication, storage and because of its database capabilities.

Several reasons caused the decision to do it again, but with a proper backend:

  • Server Side Rendering -> SEO
  • More control over the DB and authentication
  • No sharing data with Google
  • No dependency on Firebase

Next.js was chosen because of its popularity and therefore broad availability of knowledge about it. To stay within the realms of Next.js, Auth.js was the authentication framework of choice. Auth.js allows magic link authentication and the usage of Nodemailer for that. This in return allows us to implement authentication without storing passwords and without having to depend on email providers.
For now Mysql / MariaDB is used to store and manage content, userdata and session tokens. In the future Prisma will be used to allow different database solutions easily.

The README on Github includes a how-to-get-it-to-run. This blogpost focuses on the creation of the project from the beginning.

Github

https://github.com/manuelerdoes/manusblog_next

Tech Stack

  • Next.js
  • Tailwind
  • highlight.js
  • marked
  • dompurify
  • mysql
  • Auth.js
  • Nodemailer
  • Prisma

Installation

Installation prerequisites

First some things needed to be installed. From the top to the bottom.

Node.js

Node.js allows Javascript to run on a server to use it as backend language. https://nodejs.org/en

Mysql or MariaDB

Relational database.
Linux: package manager
Windows: https://dev.mysql.com/downloads/installer/
macOS: https://formulae.brew.sh/formula/mysql

I created an extra user and database and granted all rights to the user to this database. On the productive server I made sure to run the script that secures the mysql configuration.
The project on Github includes a file prepare_mysql.sh. It's a bash script that creates the blog database. The authentication database is created automatically in the process of configuring Auth.js.

Next.js project

A new Node.js project was started according to the official documentation:
https://nextjs.org/docs/app/getting-started/installation

The project was created with the following options:

What is your project named?
Would you like to use TypeScript? No
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like your code inside a src/ directory? No
Would you like to use App Router? (recommended) Yes
Would you like to customize the import alias (@/* by default)? No

Auth.js

Auth.js allows to implement all the popular authentication methods in a seemgly easy way. It's relatively new and it shows. To get it to work in this project was not hassle free to say the least. The documentation was followed for a basic install but for further configuration other sources of information were needed because the documentaion seemed not be up-to-date.

This youtube video helped: https://www.youtube.com/watch?v=TLGFTH4s_0Y&list=PLg3wmDvUMTPv-NtkMTJF_tDFGqob80p66&index=11

https://authjs.dev/getting-started/installation?framework=next-js

So the official documentation was followed to install it and to create the necessary files. This documentation will go into the configuration of Auth.js further on. Also the part of installing Nodemailer as magic link provider was followed. This part of the documentation also included the installation of Prisma as database adapter for the authentication database.

Additional NPM packages

The package.json file reveals that there are other NPM packages that have been installed. All of them were installed with npm i package-name.

Package Comment
date-fns Used to sort the search results by date.
highlight.js Syntax highlights in code parts of the blogposts.
isomorphic-dompurify Sanitizes markup before it gets rendered in the browser. The isomorphic version allows it to run on the client and server side.
lodash To debounce the search input.
marked Converts markdown to html.
marked-highlight To make the syntax highlighting work together with highlight.js.
mysql2 Create mysql connections and even pools of connections. Also allows to query the db(s).
nanoid Generates small unique identifiers. They are used to make unique slugs together with the blogpost titles.
next-themes Used for the topic-based themes.
slugify Cerates the blog slugs out of the blogpost titles and the uid generated by nanoid.
swr Library for easy data fetching with minimal code from the Next.js creators.

Component tree

https://bitesnbytes.ch/files/xF3g--component_tree.pdf

The goal is to use server rendering as much as possible. This is not the case right now, so there is room for improvement. What can be seen on the diagram is that the blog content is rendered on the server. But if the user who reads it is authenticated, the content gets served by a client component. This is because difficulties with authenticated requests from server components have been encountered. For now loading times without authorisation are fast and SEO is possible. Also are not-authorised users prevented from accessing not-public blogposts. The downside is the slower loading time when users are logged in.