June 30, 2022

How I built this blog

 I've benefited a lot from other developers sharing how they build things, so below is a summary of how I built this blog, and here's the code if you want to use it, extend it, or send suggestions.

I'll explain how I built it with an example. When the user types mthurmond.org in their browser and hits enter, the request goes to the name server, which forwards it to the mthurmond.org IP address. I used Google Domains to buy this domain and it forwards requests to Render, my hosting service.

Simplified tech stack


When Render gets the request, it hits a server running Node that uses Express for the middleware. Express matches the route the user requested to the appropriate content. If the user visits the homepage route "/", Express uses Sequelize, an ORM, to query the Postgres database. The query gets the last 10 posts, uses a regex to parse only the first few sentences, and then embeds that data into the appropriate view. 
 
Pug is the view engine and Bootstrap is used for the components. Once Express has data from the database, it populates the Pug template and sends it back to the client, i.e. the user, as plain html. Once the html loads on the user's browser, it fetches any static js and css files, which are also hosted in Express folders on the server. The browser also fetches any images, which are hosted on a free AWS service. 

To compose a post, the user goes to the "/new" route and a Trix WYSIWYG editor is loaded. This open-source tool lets the user create formatted content, and then saves it to the database as html. It also supports image uploads. 

The user has to register and then login to create, edit, or delete posts. User data is stored in the Users table in Postgres, and their password is hashed with the bcrypt node package. I use an environment variable to ensure that only I can register and login, but it can be removed later to allow new users to signup. 

There are other cool features too, like maintaining draft posts and limiting server responses for cost and security reasons. To see more, checkout the code, which is linked above and in the footer.