Thu Mar 04 2021Revamping My Landing Page

GitHub Repo

1. Backstory

Since I don't actively use social media anymore, I had a need to create my own landing page so people could at least Google me and check that I am still alive. Hence, I created a landing page, built with the technologies that will serve me for a long time without too much hassle and obviously for free. Thus, I decided to use Netlify to host a single-page-application using either React or Vue with some Serverless functionalities like an emailer. In this case, I wouldn't even pay a single penny and I could host the page free forever. So, I built it.

1.1. Why it was a good solution?

It was overall a good solution since I paid nothing, and served me quite well. It was SEO friendly, comes up first in the search when people search me, gives brief information about myself and offers the user to contact me without even opening their mail application. It was all you ask for from a landing page, that was for sure.

1.2. Why it was not the best solution?

First of all, I strongly dislike Twitter but I also have ✨things to say✨.

A couple of months later, I decided to open up a blog where I can write things, specifically the toy projects I was building. It's a very effective process of teaching myself and checking the things I made retrospectively.

Since, I already had the landing page I thought about building the blog on top of it; but then I decided not to. I wanted to keep things as simple as possible because I just didn't want to maintain stuff. I hate maintaining things. However, if I need to write about it, it would be another blog post.

I gave my reasons for preferring Jamstack for small scale applications, such as blogs before. The primary reason is, it is absolutely cheaper than free, and faster than any other websites you will visit. This is because the content is being generated at the build time.

notion image

I chose a Jekyll template to host a static blog where I use markdown for my blog posts. To this day, I still think Jekyll is one of the best solutions for hosting static content out there. If I ever have a marketing page for a product that I own, I would definitely use Jekyll. There is no need to look for exciting technologies.

So, I created my blog with Jekyll and hosted it on another domain. Now, I had to maintain two applications (the landing page and the blog), and I could only write the blog posts on my computer because I didn't have a dedicated markdown editor where I can run Jekyll and see how it looks like. I was stuck.

As photography is a big part of my life (I do even earn a considerable amount of money out of it), I always had the plan to create my own portfolio. I could use third party services such as Flickr, or I could build my own, and if you know me I always build things on my own. I like cooking my own food, I like to fix broken stuff, that is who I am. So, after some thought process, I decided to build my own portfolio and that is where I realised I was in an application hell. I had to keep everything in a single domain.

These were my requirements:

  • I had to have a single application where I keep various stuff such as landing page, blog, photo portfolio etc.
  • This needs to be completely free. I hate spending money.
  • I should be able to write blog posts whenever I want.

2. Picking Next.js

First of all, I certainly didn't need a fully blown full-stack application. Besides, I need a server and that thing costs money. If I need backend logic, I could use serverless technologies easily. There are WebSockets, Redis instances available for serverless configurations so it was fine. I didn't need too much dynamic content anyway.

2.1. Data Fetching

Next.js offers data fetching pretty simplified, and in this project I use all of them

  • getServerSideProps ⇒ fetch data on each request
  • getStaticProps ⇒ fetch data at build time
  • getStaticPaths ⇒ specify dynamic routes to pre-render pages based on data

Here is a brief explanation from Next.js documentation:

When should I use getServerSideProps?

You should use getServerSideProps only if you need to pre-render a page whose data must be fetched at request time. Time to first byte (TTFB) will be slower than getStaticProps because the server must compute the result on every request, and the result cannot be cached by a CDN without extra configuration.

When should I use getStaticProps?

You should use getStaticProps if:

  • The data required to render the page is available at build time ahead of a user’s request.
  • The data comes from a headless CMS.
  • The data can be publicly cached (not user-specific).
  • The page must be pre-rendered (for SEO) and be very fast — getStaticPropsgenerates HTML and JSON files, both of which can be cached by a CDN for performance.

When should I use getStaticPaths?

You should use getStaticPaths if you’re statically pre-rendering pages that use dynamic routes.

2.2. Summary

In other words, Next.js offered me to build high-quality pages with scaling in mind. For instance, if I ever build the photo portfolio, I could use next/image library to serve optimised photos quite easily.

3. Picking Notion as a CMS

What is CMS? According to Wikipedia:

A content management system is a computer software used to manage the creation and modification of digital content.

In other words, the CMS would be my BPMS (Blog Post Management System).

3.1. Options

3.1.1. Headless CMS Technologies

There are really nice headless CMS options such as WordPress, ButterCMS, or Strapi. However, these services are product and marketing oriented and can be overkill for a personal blog. They offer a web editor which can be used from mobile devices like a tablet or smartphone, but integrating with such service would just be maintaining another product which I was trying to run away from the first place.

3.1.2. Markdown

MDX is very easy to set up and use with Next.js, they even have official documentation and tutorials to start and go in no time. I thought about using it until I realised one of my requirements was maintaining my posts from other devices. I don't know about you but I really didn't want to write a markdown from my phone on a bus.

3.1.3. Notion

Notion is, although slow, an amazing application that I use daily for personal and work reasons. They offer a nice and intuitive interface where you can also export the content in markdown, PDF or HTML.

Styling is extremely easy, they have applications for all the platforms and I keep using the premium version of the application with my student e-mail address for free.

3.2. Why Notion is the best for me?

The photographer Chase Jarvis coined the phrase “the best camera is the one that’s with you“. He meant that having a crappy instamatic with you at an important moment is better than having the best camera in the world locked up in your car.

I thought about the "the best camera" a lot. The best things that come to my mind didn't come to me when I study or work or even when I was at my desk. I was away from my computer nearly all the time, but I always keep my iPhone near me and take quick notes for almost everything.

In contrast, my phone was the best camera as well as the best notebook for scraping ideas. It was crucially important to me to write the posts remotely and Notion does that no other app ever could.

Writing a blog post from my iPad.
Writing a blog post from my iPad.

4. Combining Next.js and Notion

With all the reasons I explained above, it was very straightforward and such a joy to create a static blog using React and Notion, there were rendering libraries and API Workers for Notion where people already reverse engineered and found a way to export text blocks. All I had to do is creating a table and tailor it for my needs.

My Notion Table where I keep the posts as individual pages.
My Notion Table where I keep the posts as individual pages.

During build time, I make a query to my Notion Table and get all my published blog posts with using getStaticProps

export async function getStaticProps() {
  let posts = await getAllPosts();
  return {
    props: {
      posts: posts.filter((post) => post.published),

In [slug].tsx file I use getStatichPaths to create the routing for each post.

export async function getStaticPaths() {
  let posts = await getAllPosts();
  posts = posts.filter((post) => post.published)
  const paths = => `/blog/${row.slug}`);
  return {
    fallback: false,

Yes, it is that easy! Sending love to the guys and gals at Vercel.

As a reader, I hope that you will enjoy the new blog!


Stay up-to-date

Subscribe to my newsletter and stay up-to-date. Why not? It's free.